Skip to content

Commit e0acc25

Browse files
dlei6ggfxbot
authored andcommitted
InlineAsm Prototype
Change-Id: If0584fc3523ef920325b9f89f07a5327beebec44
1 parent ff00839 commit e0acc25

25 files changed

+1215
-468
lines changed

IGC/Compiler/CISACodeGen/CISABuilder.cpp

Lines changed: 262 additions & 146 deletions
Large diffs are not rendered by default.

IGC/Compiler/CISACodeGen/CISABuilder.hpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3030

3131
#include "visa_wa.h"
3232

33-
3433
namespace IGC
3534
{
3635
class CShader;
@@ -131,6 +130,8 @@ class CEncoder
131130
{
132131
public:
133132
void InitEncoder( bool canAbortOnSpill, bool hasStackCall);
133+
void InitBuildParams(llvm::SmallVector<const char*, 10> &params);
134+
void InitVISABuilderOptions(TARGET_PLATFORM VISAPlatform, bool canAbortOnSpill, bool hasStackCall);
134135
SEncoderState CopyEncoderState();
135136
void SetEncoderState(SEncoderState &newState);
136137

@@ -344,6 +345,7 @@ class CEncoder
344345
void Wait();
345346

346347
VISAKernel* GetVISAKernel() { return vKernel; }
348+
VISABuilder* GetVISABuilder() { return vbuilder; }
347349
void Init();
348350
void Push();
349351

@@ -396,6 +398,9 @@ class CEncoder
396398

397399
void AddFunctionSymbol(llvm::Function* F, CVariable* fvar);
398400

401+
std::string GetVariableName(CVariable* var);
402+
std::string GetDumpFileName(std::string extension);
403+
399404
private:
400405
// helper functions
401406
VISA_VectorOpnd* GetSourceOperand(CVariable* var, const SModifier& mod);
@@ -501,6 +506,11 @@ class CEncoder
501506

502507
uint32_t getNumChannels(CVariable* var) const;
503508

509+
void SaveOption(vISAOptions option, bool val);
510+
void SaveOption(vISAOptions option, uint32_t val);
511+
void SaveOption(vISAOptions option, const char* val);
512+
void SetBuilderOptions(VISABuilder* pbuilder);
513+
504514
protected:
505515
// encoder states
506516
SEncoderState m_encoderState;
@@ -509,6 +519,22 @@ class CEncoder
509519

510520
VISA_WA_TABLE m_WaTable;
511521

522+
enum OpType
523+
{
524+
ET_BOOL,
525+
ET_INT32,
526+
ET_CSTR
527+
};
528+
struct OptionValue
529+
{
530+
OpType type;
531+
bool vBool;
532+
uint32_t vInt32;
533+
const char* vCstr;
534+
};
535+
// List of vISA user options
536+
std::vector<std::pair<vISAOptions, OptionValue>> m_visaUserOptions;
537+
512538
// Typically IGC just use ones vKernel for every vISA::compile call,
513539
// in those cases, vKernel and vMainKernel should be the same.
514540
// Only when using stack-call, vKernel pointer changes every time
@@ -517,8 +543,10 @@ class CEncoder
517543
VISAKernel* vKernel;
518544
VISAKernel* vMainKernel;
519545
VISABuilder* vbuilder;
546+
VISABuilder* vAsmTextBuilder;
520547

521548
bool m_enableVISAdump;
549+
bool m_hasInlineAsm;
522550
std::vector<VISA_LabelOpnd*> labelMap;
523551

524552
/// Per kernel label counter

IGC/Compiler/CISACodeGen/CheckInstrTypes.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ CheckInstrTypes::CheckInstrTypes(IGC::SInstrTypes* instrList) : FunctionPass(ID)
6464
instrList->hasLoadStore = false;
6565
instrList->hasCall = false;
6666
instrList->hasIndirectCall = false;
67+
instrList->hasInlineAsm = false;
6768
instrList->hasIndirectBranch = false;
6869
instrList->hasFunctionAddressTaken = false;
6970
instrList->hasSel = false;
@@ -148,6 +149,7 @@ void CheckInstrTypes::visitCallInst(CallInst &C)
148149
{
149150
if (C.isInlineAsm())
150151
{
152+
g_InstrTypes->hasInlineAsm = true;
151153
return;
152154
}
153155
// calls to 'blocks' have a null Function object

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7473,6 +7473,76 @@ void EmitPass::EmitIntrinsicMessage(llvm::IntrinsicInst* inst)
74737473
}
74747474
}
74757475

7476+
// Parse the inlined asm string to generate VISA operands
7477+
// Example: "mul (M1, 16) $0(0, 0)<1> $1(0, 0)<1;1,0> $2(0, 0)<1;1,0>", "=r,r,r"(float %6, float %7)
7478+
void EmitPass::EmitInlineAsm(llvm::CallInst* inst)
7479+
{
7480+
std::stringstream &str = m_encoder->GetVISABuilder()->GetAsmTextStream();
7481+
str << " ";
7482+
7483+
InlineAsm* IA = cast<InlineAsm>(inst->getCalledValue());
7484+
const char* asmStr = IA->getAsmString().c_str();
7485+
const char* lastEmitted = asmStr;
7486+
smallvector<CVariable*, 8> opnds;
7487+
opnds.push_back(m_destination);
7488+
for (unsigned i = 0; i < inst->getNumArgOperands(); i++)
7489+
{
7490+
CVariable* cv = GetSymbol(inst->getArgOperand(i));
7491+
opnds.push_back(cv);
7492+
}
7493+
7494+
while (*lastEmitted)
7495+
{
7496+
switch (*lastEmitted)
7497+
{
7498+
default:
7499+
{
7500+
const char* literalEnd = lastEmitted + 1;
7501+
while (*literalEnd && *literalEnd != '{' && *literalEnd != '|' &&
7502+
*literalEnd != '}' && *literalEnd != '$' && *literalEnd != '\n')
7503+
{
7504+
++literalEnd;
7505+
}
7506+
str.write(lastEmitted, literalEnd - lastEmitted);
7507+
lastEmitted = literalEnd;
7508+
break;
7509+
}
7510+
case '\n':
7511+
{
7512+
++lastEmitted;
7513+
str << '\n';
7514+
break;
7515+
}
7516+
case '$':
7517+
{
7518+
++lastEmitted;
7519+
const char* idStart = lastEmitted;
7520+
const char* idEnd = idStart;
7521+
while (*idEnd >= '0' && *idEnd <= '9')
7522+
++idEnd;
7523+
7524+
unsigned val;
7525+
if (StringRef(idStart, idEnd - idStart).getAsInteger(10, val))
7526+
{
7527+
assert(0 && "Invalid operand format");
7528+
return;
7529+
}
7530+
lastEmitted = idEnd;
7531+
7532+
if (val >= opnds.size())
7533+
{
7534+
assert(0 && "Invalid operand index");
7535+
return;
7536+
}
7537+
7538+
str << m_encoder->GetVariableName(opnds[val]);
7539+
break;
7540+
}
7541+
}
7542+
}
7543+
str << " /// inlined ASM" << endl;
7544+
}
7545+
74767546
CVariable *EmitPass::Mul(CVariable *Src0, CVariable *Src1, const CVariable *DstPrototype)
74777547
{
74787548
bool IsSrc0Imm = Src0->IsImmediate();
@@ -8145,6 +8215,10 @@ void EmitPass::EmitNoModifier(llvm::Instruction* inst)
81458215
{
81468216
EmitIntrinsicMessage(I);
81478217
}
8218+
else if (cast<CallInst>(inst)->isInlineAsm())
8219+
{
8220+
EmitInlineAsm(cast<CallInst>(inst));
8221+
}
81488222
else
81498223
{
81508224
emitCall(cast<CallInst>(inst));

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3535

3636
#include "common/LLVMWarningsPush.hpp"
3737
#include <llvm/IR/DataLayout.h>
38+
#include <llvm/IR/InlineAsm.h>
3839
#include "llvm/IR/GetElementPtrTypeIterator.h"
3940
#include "common/LLVMWarningsPop.hpp"
4041
#include "Compiler/IGCPassSupport.h"
@@ -126,7 +127,8 @@ class EmitPass : public llvm::FunctionPass
126127
void EmitSubPair(llvm::GenIntrinsicInst *GII, const SSource Sources[4], const DstModifier &DstMod);
127128
void EmitMulPair(llvm::GenIntrinsicInst *GII, const SSource Sources[4], const DstModifier &DstMod);
128129
void EmitPtrToPair(llvm::GenIntrinsicInst *GII, const SSource Sources[1], const DstModifier &DstMod);
129-
130+
void EmitInlineAsm(llvm::CallInst* inst);
131+
130132
void emitPairToPtr(llvm::GenIntrinsicInst *GII);
131133

132134
void emitMulAdd16(llvm::Instruction* I, const SSource source[2], const DstModifier &dstMod);

IGC/Compiler/CISACodeGen/PatternMatchPass.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3131
#include "common/igc_regkeys.hpp"
3232

3333
#include "common/LLVMWarningsPush.hpp"
34+
#include <llvm/IR/InlineAsm.h>
3435
#include <llvm/IR/Dominators.h>
3536
#include <llvm/IR/Constants.h>
3637
#include <llvm/IR/Instruction.h>
@@ -1126,14 +1127,24 @@ void CodeGenPatternMatch::visitCallInst(CallInst &I)
11261127
match = MatchSingleInstruction(I);
11271128
}
11281129
}
1129-
else if(I.isInlineAsm())
1130+
else if (!I.getCalledFunction())
11301131
{
1131-
return;
1132-
}
1133-
else if (IGC_IS_FLAG_ENABLED(EnableFunctionPointer) && !I.getCalledFunction())
1134-
{
1135-
// Match indirect call
1136-
match = MatchSingleInstruction(I);
1132+
// Match inline asm or indirect call
1133+
if (I.isInlineAsm())
1134+
{
1135+
if (IGC_IS_FLAG_ENABLED(EnableInlineAsmSupport))
1136+
{
1137+
match = MatchSingleInstruction(I);
1138+
}
1139+
else
1140+
{
1141+
return;
1142+
}
1143+
}
1144+
else if (IGC_IS_FLAG_ENABLED(EnableFunctionPointer))
1145+
{
1146+
match = MatchSingleInstruction(I);
1147+
}
11371148
}
11381149

11391150
assert(match && "no match for this call");

IGC/Compiler/CodeGenPublic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ namespace IGC
142142
bool hasLoadStore;
143143
bool hasCall;
144144
bool hasIndirectCall;
145+
bool hasInlineAsm;
145146
bool hasIndirectBranch;
146147
bool hasFunctionAddressTaken;
147148
bool hasSel;

IGC/common/igc_flags.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ DECLARE_IGC_REGKEY(bool, AdvRuntimeUnrollCount, 0, "Advanced runtime
252252
DECLARE_IGC_REGKEY(bool, EnableAdvMemOpt, true, "Enable advanced memory optimization")
253253
DECLARE_IGC_REGKEY(bool, UniformMemOptLimit, 0, "Limit of uniform memory optimization in bits")
254254
DECLARE_IGC_REGKEY(bool, EnableFunctionPointer, false, "Enables support for function pointers and indirect calls")
255+
DECLARE_IGC_REGKEY(bool, EnableInlineAsmSupport, false, "Enables support for inlineAsm calls")
255256

256257
DECLARE_IGC_REGKEY(bool, EnableReadGTPinInput, true, "Enables setting GTPin context flags by reading the input to the compiler adapters")
257258

visa/BuildCISAIR.h

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ class CisaBinary;
3636
class VISAKernelImpl;
3737
class VISAFunction;
3838

39-
#ifndef DLL_MODE
4039
extern FILE *CISAin;
4140
extern FILE *CISAout;
4241
extern int CISAdebug;
43-
#endif
4442

4543
#include "VISABuilderAPIDefinition.h"
4644
#include "visa_wa.h"
@@ -72,12 +70,17 @@ class CISA_IR_Builder : public VISABuilder
7270

7371
CISA_IR_Builder(CM_VISA_BUILDER_OPTION buildOption, int majorVersion, int minorVersion, PVISA_WA_TABLE pWaTable) : m_mem(4096)
7472
{
73+
memset(&m_header, 0, sizeof(m_header));
74+
7575
mBuildOption = buildOption;
7676
m_executionSatarted = false;
7777
m_kernel_count = 0;
7878
m_function_count = 0;
79-
m_majorVersion = majorVersion;
80-
m_minorVersion = minorVersion;
79+
80+
m_header.major_version = majorVersion;
81+
m_header.minor_version = minorVersion;
82+
m_header.magic_number = COMMON_ISA_MAGIC_NUM;
83+
8184
m_cisaBinary = new (m_mem) CisaFramework::CisaBinary(&m_options);
8285
m_currentKernel = NULL;
8386
m_pWaTable = pWaTable;
@@ -101,9 +104,10 @@ class CISA_IR_Builder : public VISABuilder
101104
return true;
102105
}
103106

104-
void closeCISAParsingFile() {fclose(CISAin);}
107+
void closeCISAParsingFile() { fclose(CISAin); }
105108

106109
#endif
110+
107111
/**************START VISA BUILDER API*****************************/
108112

109113
static int CreateBuilder(CISA_IR_Builder *&builder,
@@ -125,18 +129,26 @@ class CISA_IR_Builder : public VISABuilder
125129
CM_BUILDER_API void SetOption(vISAOptions option, uint32_t val) { m_options.setOption(option, val); }
126130
CM_BUILDER_API void SetOption(vISAOptions option, const char *val) { m_options.setOption(option, val); }
127131

132+
// Used for inline asm code generation
133+
CM_BUILDER_API virtual int ParseVISAText(const std::string& visaHeader, const std::string& visaText, const std::string& visaTextFile);
134+
CM_BUILDER_API virtual int WriteVISAHeader();
135+
CM_BUILDER_API std::stringstream& GetAsmTextStream() { return m_ssIsaAsm; }
136+
CM_BUILDER_API std::stringstream& GetAsmTextHeaderStream() { return m_ssIsaAsmHeader; }
137+
CM_BUILDER_API virtual VISAKernel* GetKernel();
138+
128139
/**************END VISA BUILDER API*************************/
129140

130141
string_pool_entry** branch_targets;
142+
common_isa_header m_header;
131143

132144
VISAKernelImpl *m_kernel;
133145
CisaFramework::CisaBinary *m_cisaBinary;
134146
VISAKernelImpl * get_kernel() { return m_kernel; }
135147

136148
void CISA_IR_setVersion(unsigned char major_ver, unsigned char minor_ver)
137149
{
138-
m_majorVersion = major_ver;
139-
m_minorVersion = minor_ver;
150+
m_header.major_version = major_ver;
151+
m_header.minor_version = minor_ver;
140152
}
141153

142154
Common_ISA_Input_Class get_input_class(Common_ISA_Var_Class var_class);
@@ -754,6 +766,8 @@ class CISA_IR_Builder : public VISABuilder
754766
void setTestName(std::string name) { testName = name; }
755767

756768
Options m_options;
769+
std::stringstream m_ssIsaAsm;
770+
std::stringstream m_ssIsaAsmHeader;
757771

758772
void setupNativeRelocs(unsigned int, const BasicRelocEntry*);
759773
NativeRelocs* getNativeRelocs(bool createIfNULL = true)
@@ -778,8 +792,6 @@ class CISA_IR_Builder : public VISABuilder
778792

779793
unsigned int m_kernel_count;
780794
unsigned int m_function_count;
781-
int m_majorVersion;
782-
int m_minorVersion;
783795

784796
std::list<VISAKernelImpl *> m_kernels;
785797
//keeps track of functions for stitching purposes, after compilation.
@@ -803,4 +815,5 @@ class CISA_IR_Builder : public VISABuilder
803815
void* gtpin_init = nullptr;
804816
};
805817
extern _THREAD CISA_IR_Builder * pCisaBuilder;
818+
806819
#endif

0 commit comments

Comments
 (0)