SkSLJIT.cpp 91 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931
  1. /*
  2. * Copyright 2018 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SKSL_STANDALONE
  8. #ifdef SK_LLVM_AVAILABLE
  9. #include "src/sksl/SkSLJIT.h"
  10. #include "src/core/SkCpu.h"
  11. #include "src/core/SkRasterPipeline.h"
  12. #include "src/sksl/ir/SkSLAppendStage.h"
  13. #include "src/sksl/ir/SkSLExpressionStatement.h"
  14. #include "src/sksl/ir/SkSLFunctionCall.h"
  15. #include "src/sksl/ir/SkSLFunctionReference.h"
  16. #include "src/sksl/ir/SkSLIndexExpression.h"
  17. #include "src/sksl/ir/SkSLProgram.h"
  18. #include "src/sksl/ir/SkSLUnresolvedFunction.h"
  19. #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
  20. static constexpr int MAX_VECTOR_COUNT = 16;
  21. extern "C" void sksl_pipeline_append(SkRasterPipeline* p, int stage, void* ctx) {
  22. p->append((SkRasterPipeline::StockStage) stage, ctx);
  23. }
  24. #define PTR_SIZE sizeof(void*)
  25. extern "C" void sksl_pipeline_append_callback(SkRasterPipeline* p, void* fn) {
  26. p->append(fn, nullptr);
  27. }
  28. extern "C" void sksl_debug_print(float f) {
  29. printf("Debug: %f\n", f);
  30. }
  31. extern "C" float sksl_clamp1(float f, float min, float max) {
  32. return SkTPin(f, min, max);
  33. }
  34. using float2 = __attribute__((vector_size(8))) float;
  35. using float3 = __attribute__((vector_size(16))) float;
  36. using float4 = __attribute__((vector_size(16))) float;
  37. extern "C" float2 sksl_clamp2(float2 f, float min, float max) {
  38. return float2 { SkTPin(f[0], min, max), SkTPin(f[1], min, max) };
  39. }
  40. extern "C" float3 sksl_clamp3(float3 f, float min, float max) {
  41. return float3 { SkTPin(f[0], min, max), SkTPin(f[1], min, max), SkTPin(f[2], min, max) };
  42. }
  43. extern "C" float4 sksl_clamp4(float4 f, float min, float max) {
  44. return float4 { SkTPin(f[0], min, max), SkTPin(f[1], min, max), SkTPin(f[2], min, max),
  45. SkTPin(f[3], min, max) };
  46. }
  47. namespace SkSL {
  48. static constexpr int STAGE_PARAM_COUNT = 12;
  49. static bool ends_with_branch(const Statement& stmt) {
  50. switch (stmt.fKind) {
  51. case Statement::kBlock_Kind: {
  52. const Block& b = (const Block&) stmt;
  53. if (b.fStatements.size()) {
  54. return ends_with_branch(*b.fStatements.back());
  55. }
  56. return false;
  57. }
  58. case Statement::kBreak_Kind: // fall through
  59. case Statement::kContinue_Kind: // fall through
  60. case Statement::kReturn_Kind: // fall through
  61. return true;
  62. default:
  63. return false;
  64. }
  65. }
  66. JIT::JIT(Compiler* compiler)
  67. : fCompiler(*compiler) {
  68. LLVMInitializeNativeTarget();
  69. LLVMInitializeNativeAsmPrinter();
  70. LLVMLinkInMCJIT();
  71. SkASSERT(!SkCpu::Supports(SkCpu::SKX)); // not yet supported
  72. if (SkCpu::Supports(SkCpu::HSW)) {
  73. fVectorCount = 8;
  74. fCPU = "haswell";
  75. } else if (SkCpu::Supports(SkCpu::AVX)) {
  76. fVectorCount = 8;
  77. fCPU = "ivybridge";
  78. } else {
  79. fVectorCount = 4;
  80. fCPU = nullptr;
  81. }
  82. fContext = LLVMContextCreate();
  83. fVoidType = LLVMVoidTypeInContext(fContext);
  84. fInt1Type = LLVMInt1TypeInContext(fContext);
  85. fInt1VectorType = LLVMVectorType(fInt1Type, fVectorCount);
  86. fInt1Vector2Type = LLVMVectorType(fInt1Type, 2);
  87. fInt1Vector3Type = LLVMVectorType(fInt1Type, 3);
  88. fInt1Vector4Type = LLVMVectorType(fInt1Type, 4);
  89. fInt8Type = LLVMInt8TypeInContext(fContext);
  90. fInt8PtrType = LLVMPointerType(fInt8Type, 0);
  91. fInt32Type = LLVMInt32TypeInContext(fContext);
  92. fInt64Type = LLVMInt64TypeInContext(fContext);
  93. fSizeTType = LLVMInt64TypeInContext(fContext);
  94. fInt32VectorType = LLVMVectorType(fInt32Type, fVectorCount);
  95. fInt32Vector2Type = LLVMVectorType(fInt32Type, 2);
  96. fInt32Vector3Type = LLVMVectorType(fInt32Type, 3);
  97. fInt32Vector4Type = LLVMVectorType(fInt32Type, 4);
  98. fFloat32Type = LLVMFloatTypeInContext(fContext);
  99. fFloat32VectorType = LLVMVectorType(fFloat32Type, fVectorCount);
  100. fFloat32Vector2Type = LLVMVectorType(fFloat32Type, 2);
  101. fFloat32Vector3Type = LLVMVectorType(fFloat32Type, 3);
  102. fFloat32Vector4Type = LLVMVectorType(fFloat32Type, 4);
  103. }
  104. JIT::~JIT() {
  105. LLVMOrcDisposeInstance(fJITStack);
  106. LLVMContextDispose(fContext);
  107. }
  108. void JIT::addBuiltinFunction(const char* ourName, const char* realName, LLVMTypeRef returnType,
  109. std::vector<LLVMTypeRef> parameters) {
  110. bool found = false;
  111. for (const auto& pair : *fProgram->fSymbols) {
  112. if (Symbol::kFunctionDeclaration_Kind == pair.second->fKind) {
  113. const FunctionDeclaration& f = (const FunctionDeclaration&) *pair.second;
  114. if (pair.first != ourName || returnType != this->getType(f.fReturnType) ||
  115. parameters.size() != f.fParameters.size()) {
  116. continue;
  117. }
  118. for (size_t i = 0; i < parameters.size(); ++i) {
  119. if (parameters[i] != this->getType(f.fParameters[i]->fType)) {
  120. goto next;
  121. }
  122. }
  123. fFunctions[&f] = LLVMAddFunction(fModule, realName, LLVMFunctionType(returnType,
  124. parameters.data(),
  125. parameters.size(),
  126. false));
  127. found = true;
  128. }
  129. if (Symbol::kUnresolvedFunction_Kind == pair.second->fKind) {
  130. // FIXME consolidate this with the code above
  131. for (const auto& f : ((const UnresolvedFunction&) *pair.second).fFunctions) {
  132. if (pair.first != ourName || returnType != this->getType(f->fReturnType) ||
  133. parameters.size() != f->fParameters.size()) {
  134. continue;
  135. }
  136. for (size_t i = 0; i < parameters.size(); ++i) {
  137. if (parameters[i] != this->getType(f->fParameters[i]->fType)) {
  138. goto next;
  139. }
  140. }
  141. fFunctions[f] = LLVMAddFunction(fModule, realName, LLVMFunctionType(
  142. returnType,
  143. parameters.data(),
  144. parameters.size(),
  145. false));
  146. found = true;
  147. }
  148. }
  149. next:;
  150. }
  151. SkASSERT(found);
  152. }
  153. void JIT::loadBuiltinFunctions() {
  154. this->addBuiltinFunction("abs", "fabs", fFloat32Type, { fFloat32Type });
  155. this->addBuiltinFunction("sin", "sinf", fFloat32Type, { fFloat32Type });
  156. this->addBuiltinFunction("cos", "cosf", fFloat32Type, { fFloat32Type });
  157. this->addBuiltinFunction("tan", "tanf", fFloat32Type, { fFloat32Type });
  158. this->addBuiltinFunction("sqrt", "sqrtf", fFloat32Type, { fFloat32Type });
  159. this->addBuiltinFunction("clamp", "sksl_clamp1", fFloat32Type, { fFloat32Type,
  160. fFloat32Type,
  161. fFloat32Type });
  162. this->addBuiltinFunction("clamp", "sksl_clamp2", fFloat32Vector2Type, { fFloat32Vector2Type,
  163. fFloat32Type,
  164. fFloat32Type });
  165. this->addBuiltinFunction("clamp", "sksl_clamp3", fFloat32Vector3Type, { fFloat32Vector3Type,
  166. fFloat32Type,
  167. fFloat32Type });
  168. this->addBuiltinFunction("clamp", "sksl_clamp4", fFloat32Vector4Type, { fFloat32Vector4Type,
  169. fFloat32Type,
  170. fFloat32Type });
  171. this->addBuiltinFunction("print", "sksl_debug_print", fVoidType, { fFloat32Type });
  172. }
  173. uint64_t JIT::resolveSymbol(const char* name, JIT* jit) {
  174. LLVMOrcTargetAddress result;
  175. if (!LLVMOrcGetSymbolAddress(jit->fJITStack, &result, name)) {
  176. if (!strcmp(name, "_sksl_pipeline_append")) {
  177. result = (uint64_t) &sksl_pipeline_append;
  178. } else if (!strcmp(name, "_sksl_pipeline_append_callback")) {
  179. result = (uint64_t) &sksl_pipeline_append_callback;
  180. } else if (!strcmp(name, "_sksl_clamp1")) {
  181. result = (uint64_t) &sksl_clamp1;
  182. } else if (!strcmp(name, "_sksl_clamp2")) {
  183. result = (uint64_t) &sksl_clamp2;
  184. } else if (!strcmp(name, "_sksl_clamp3")) {
  185. result = (uint64_t) &sksl_clamp3;
  186. } else if (!strcmp(name, "_sksl_clamp4")) {
  187. result = (uint64_t) &sksl_clamp4;
  188. } else if (!strcmp(name, "_sksl_debug_print")) {
  189. result = (uint64_t) &sksl_debug_print;
  190. } else {
  191. result = llvm::RTDyldMemoryManager::getSymbolAddressInProcess(name);
  192. }
  193. }
  194. SkASSERT(result);
  195. return result;
  196. }
  197. LLVMValueRef JIT::compileFunctionCall(LLVMBuilderRef builder, const FunctionCall& fc) {
  198. LLVMValueRef func = fFunctions[&fc.fFunction];
  199. SkASSERT(func);
  200. std::vector<LLVMValueRef> parameters;
  201. for (const auto& a : fc.fArguments) {
  202. parameters.push_back(this->compileExpression(builder, *a));
  203. }
  204. return LLVMBuildCall(builder, func, parameters.data(), parameters.size(), "");
  205. }
  206. LLVMTypeRef JIT::getType(const Type& type) {
  207. switch (type.kind()) {
  208. case Type::kOther_Kind:
  209. if (type.name() == "void") {
  210. return fVoidType;
  211. }
  212. SkASSERT(type.name() == "SkRasterPipeline");
  213. return fInt8PtrType;
  214. case Type::kScalar_Kind:
  215. if (type.isSigned() || type.isUnsigned()) {
  216. return fInt32Type;
  217. }
  218. if (type.isUnsigned()) {
  219. return fInt32Type;
  220. }
  221. if (type.isFloat()) {
  222. return fFloat32Type;
  223. }
  224. SkASSERT(type.name() == "bool");
  225. return fInt1Type;
  226. case Type::kArray_Kind:
  227. return LLVMPointerType(this->getType(type.componentType()), 0);
  228. case Type::kVector_Kind:
  229. if (type.name() == "float2" || type.name() == "half2") {
  230. return fFloat32Vector2Type;
  231. }
  232. if (type.name() == "float3" || type.name() == "half3") {
  233. return fFloat32Vector3Type;
  234. }
  235. if (type.name() == "float4" || type.name() == "half4") {
  236. return fFloat32Vector4Type;
  237. }
  238. if (type.name() == "int2" || type.name() == "short2" || type.name == "byte2") {
  239. return fInt32Vector2Type;
  240. }
  241. if (type.name() == "int3" || type.name() == "short3" || type.name == "byte3") {
  242. return fInt32Vector3Type;
  243. }
  244. if (type.name() == "int4" || type.name() == "short4" || type.name == "byte3") {
  245. return fInt32Vector4Type;
  246. }
  247. // fall through
  248. default:
  249. ABORT("unsupported type");
  250. }
  251. }
  252. void JIT::setBlock(LLVMBuilderRef builder, LLVMBasicBlockRef block) {
  253. fCurrentBlock = block;
  254. LLVMPositionBuilderAtEnd(builder, block);
  255. }
  256. std::unique_ptr<JIT::LValue> JIT::getLValue(LLVMBuilderRef builder, const Expression& expr) {
  257. switch (expr.fKind) {
  258. case Expression::kVariableReference_Kind: {
  259. class PointerLValue : public LValue {
  260. public:
  261. PointerLValue(LLVMValueRef ptr)
  262. : fPointer(ptr) {}
  263. LLVMValueRef load(LLVMBuilderRef builder) override {
  264. return LLVMBuildLoad(builder, fPointer, "lvalue load");
  265. }
  266. void store(LLVMBuilderRef builder, LLVMValueRef value) override {
  267. LLVMBuildStore(builder, value, fPointer);
  268. }
  269. private:
  270. LLVMValueRef fPointer;
  271. };
  272. const Variable* var = &((VariableReference&) expr).fVariable;
  273. if (var->fStorage == Variable::kParameter_Storage &&
  274. !(var->fModifiers.fFlags & Modifiers::kOut_Flag) &&
  275. fPromotedParameters.find(var) == fPromotedParameters.end()) {
  276. // promote parameter to variable
  277. fPromotedParameters.insert(var);
  278. LLVMPositionBuilderAtEnd(builder, fAllocaBlock);
  279. LLVMValueRef alloca = LLVMBuildAlloca(builder, this->getType(var->fType),
  280. String(var->fName).c_str());
  281. LLVMBuildStore(builder, fVariables[var], alloca);
  282. LLVMPositionBuilderAtEnd(builder, fCurrentBlock);
  283. fVariables[var] = alloca;
  284. }
  285. LLVMValueRef ptr = fVariables[var];
  286. return std::unique_ptr<LValue>(new PointerLValue(ptr));
  287. }
  288. case Expression::kTernary_Kind: {
  289. class TernaryLValue : public LValue {
  290. public:
  291. TernaryLValue(JIT* jit, LLVMValueRef test, std::unique_ptr<LValue> ifTrue,
  292. std::unique_ptr<LValue> ifFalse)
  293. : fJIT(*jit)
  294. , fTest(test)
  295. , fIfTrue(std::move(ifTrue))
  296. , fIfFalse(std::move(ifFalse)) {}
  297. LLVMValueRef load(LLVMBuilderRef builder) override {
  298. LLVMBasicBlockRef trueBlock = LLVMAppendBasicBlockInContext(
  299. fJIT.fContext,
  300. fJIT.fCurrentFunction,
  301. "true ? ...");
  302. LLVMBasicBlockRef falseBlock = LLVMAppendBasicBlockInContext(
  303. fJIT.fContext,
  304. fJIT.fCurrentFunction,
  305. "false ? ...");
  306. LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(fJIT.fContext,
  307. fJIT.fCurrentFunction,
  308. "ternary merge");
  309. LLVMBuildCondBr(builder, fTest, trueBlock, falseBlock);
  310. fJIT.setBlock(builder, trueBlock);
  311. LLVMValueRef ifTrue = fIfTrue->load(builder);
  312. LLVMBuildBr(builder, merge);
  313. fJIT.setBlock(builder, falseBlock);
  314. LLVMValueRef ifFalse = fIfTrue->load(builder);
  315. LLVMBuildBr(builder, merge);
  316. fJIT.setBlock(builder, merge);
  317. LLVMTypeRef type = LLVMPointerType(LLVMTypeOf(ifTrue), 0);
  318. LLVMValueRef phi = LLVMBuildPhi(builder, type, "?");
  319. LLVMValueRef incomingValues[2] = { ifTrue, ifFalse };
  320. LLVMBasicBlockRef incomingBlocks[2] = { trueBlock, falseBlock };
  321. LLVMAddIncoming(phi, incomingValues, incomingBlocks, 2);
  322. return phi;
  323. }
  324. void store(LLVMBuilderRef builder, LLVMValueRef value) override {
  325. LLVMBasicBlockRef trueBlock = LLVMAppendBasicBlockInContext(
  326. fJIT.fContext,
  327. fJIT.fCurrentFunction,
  328. "true ? ...");
  329. LLVMBasicBlockRef falseBlock = LLVMAppendBasicBlockInContext(
  330. fJIT.fContext,
  331. fJIT.fCurrentFunction,
  332. "false ? ...");
  333. LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(fJIT.fContext,
  334. fJIT.fCurrentFunction,
  335. "ternary merge");
  336. LLVMBuildCondBr(builder, fTest, trueBlock, falseBlock);
  337. fJIT.setBlock(builder, trueBlock);
  338. fIfTrue->store(builder, value);
  339. LLVMBuildBr(builder, merge);
  340. fJIT.setBlock(builder, falseBlock);
  341. fIfTrue->store(builder, value);
  342. LLVMBuildBr(builder, merge);
  343. fJIT.setBlock(builder, merge);
  344. }
  345. private:
  346. JIT& fJIT;
  347. LLVMValueRef fTest;
  348. std::unique_ptr<LValue> fIfTrue;
  349. std::unique_ptr<LValue> fIfFalse;
  350. };
  351. const TernaryExpression& t = (const TernaryExpression&) expr;
  352. LLVMValueRef test = this->compileExpression(builder, *t.fTest);
  353. return std::unique_ptr<LValue>(new TernaryLValue(this,
  354. test,
  355. this->getLValue(builder,
  356. *t.fIfTrue),
  357. this->getLValue(builder,
  358. *t.fIfFalse)));
  359. }
  360. case Expression::kSwizzle_Kind: {
  361. class SwizzleLValue : public LValue {
  362. public:
  363. SwizzleLValue(JIT* jit, LLVMTypeRef type, std::unique_ptr<LValue> base,
  364. std::vector<int> components)
  365. : fJIT(*jit)
  366. , fType(type)
  367. , fBase(std::move(base))
  368. , fComponents(components) {}
  369. LLVMValueRef load(LLVMBuilderRef builder) override {
  370. LLVMValueRef base = fBase->load(builder);
  371. if (fComponents.size() > 1) {
  372. LLVMValueRef result = LLVMGetUndef(fType);
  373. for (size_t i = 0; i < fComponents.size(); ++i) {
  374. LLVMValueRef element = LLVMBuildExtractElement(
  375. builder,
  376. base,
  377. LLVMConstInt(fJIT.fInt32Type,
  378. fComponents[i],
  379. false),
  380. "swizzle extract");
  381. result = LLVMBuildInsertElement(builder, result, element,
  382. LLVMConstInt(fJIT.fInt32Type, i, false),
  383. "swizzle insert");
  384. }
  385. return result;
  386. }
  387. SkASSERT(fComponents.size() == 1);
  388. return LLVMBuildExtractElement(builder, base,
  389. LLVMConstInt(fJIT.fInt32Type,
  390. fComponents[0],
  391. false),
  392. "swizzle extract");
  393. }
  394. void store(LLVMBuilderRef builder, LLVMValueRef value) override {
  395. LLVMValueRef result = fBase->load(builder);
  396. if (fComponents.size() > 1) {
  397. for (size_t i = 0; i < fComponents.size(); ++i) {
  398. LLVMValueRef element = LLVMBuildExtractElement(builder, value,
  399. LLVMConstInt(
  400. fJIT.fInt32Type,
  401. i,
  402. false),
  403. "swizzle extract");
  404. result = LLVMBuildInsertElement(builder, result, element,
  405. LLVMConstInt(fJIT.fInt32Type,
  406. fComponents[i],
  407. false),
  408. "swizzle insert");
  409. }
  410. } else {
  411. result = LLVMBuildInsertElement(builder, result, value,
  412. LLVMConstInt(fJIT.fInt32Type,
  413. fComponents[0],
  414. false),
  415. "swizzle insert");
  416. }
  417. fBase->store(builder, result);
  418. }
  419. private:
  420. JIT& fJIT;
  421. LLVMTypeRef fType;
  422. std::unique_ptr<LValue> fBase;
  423. std::vector<int> fComponents;
  424. };
  425. const Swizzle& s = (const Swizzle&) expr;
  426. return std::unique_ptr<LValue>(new SwizzleLValue(this, this->getType(s.fType),
  427. this->getLValue(builder, *s.fBase),
  428. s.fComponents));
  429. }
  430. default:
  431. ABORT("unsupported lvalue");
  432. }
  433. }
  434. JIT::TypeKind JIT::typeKind(const Type& type) {
  435. if (type.kind() == Type::kVector_Kind) {
  436. return this->typeKind(type.componentType());
  437. }
  438. if (type.fName == "int" || type.fName == "short" || type.fName == "byte") {
  439. return JIT::kInt_TypeKind;
  440. } else if (type.fName == "uint" || type.fName == "ushort" || type.fName == "ubyte") {
  441. return JIT::kUInt_TypeKind;
  442. } else if (type.fName == "float" || type.fName == "double" || type.fName == "half") {
  443. return JIT::kFloat_TypeKind;
  444. }
  445. ABORT("unsupported type: %s\n", type.description().c_str());
  446. }
  447. void JIT::vectorize(LLVMBuilderRef builder, LLVMValueRef* value, int columns) {
  448. LLVMValueRef result = LLVMGetUndef(LLVMVectorType(LLVMTypeOf(*value), columns));
  449. for (int i = 0; i < columns; ++i) {
  450. result = LLVMBuildInsertElement(builder,
  451. result,
  452. *value,
  453. LLVMConstInt(fInt32Type, i, false),
  454. "vectorize");
  455. }
  456. *value = result;
  457. }
  458. void JIT::vectorize(LLVMBuilderRef builder, const BinaryExpression& b, LLVMValueRef* left,
  459. LLVMValueRef* right) {
  460. if (b.fLeft->fType.kind() == Type::kScalar_Kind &&
  461. b.fRight->fType.kind() == Type::kVector_Kind) {
  462. this->vectorize(builder, left, b.fRight->fType.columns());
  463. } else if (b.fLeft->fType.kind() == Type::kVector_Kind &&
  464. b.fRight->fType.kind() == Type::kScalar_Kind) {
  465. this->vectorize(builder, right, b.fLeft->fType.columns());
  466. }
  467. }
  468. LLVMValueRef JIT::compileBinary(LLVMBuilderRef builder, const BinaryExpression& b) {
  469. #define BINARY(SFunc, UFunc, FFunc) { \
  470. LLVMValueRef left = this->compileExpression(builder, *b.fLeft); \
  471. LLVMValueRef right = this->compileExpression(builder, *b.fRight); \
  472. this->vectorize(builder, b, &left, &right); \
  473. switch (this->typeKind(b.fLeft->fType)) { \
  474. case kInt_TypeKind: \
  475. return SFunc(builder, left, right, "binary"); \
  476. case kUInt_TypeKind: \
  477. return UFunc(builder, left, right, "binary"); \
  478. case kFloat_TypeKind: \
  479. return FFunc(builder, left, right, "binary"); \
  480. default: \
  481. ABORT("unsupported typeKind"); \
  482. } \
  483. }
  484. #define COMPOUND(SFunc, UFunc, FFunc) { \
  485. std::unique_ptr<LValue> lvalue = this->getLValue(builder, *b.fLeft); \
  486. LLVMValueRef left = lvalue->load(builder); \
  487. LLVMValueRef right = this->compileExpression(builder, *b.fRight); \
  488. this->vectorize(builder, b, &left, &right); \
  489. LLVMValueRef result; \
  490. switch (this->typeKind(b.fLeft->fType)) { \
  491. case kInt_TypeKind: \
  492. result = SFunc(builder, left, right, "binary"); \
  493. break; \
  494. case kUInt_TypeKind: \
  495. result = UFunc(builder, left, right, "binary"); \
  496. break; \
  497. case kFloat_TypeKind: \
  498. result = FFunc(builder, left, right, "binary"); \
  499. break; \
  500. default: \
  501. ABORT("unsupported typeKind"); \
  502. } \
  503. lvalue->store(builder, result); \
  504. return result; \
  505. }
  506. #define COMPARE(SFunc, SOp, UFunc, UOp, FFunc, FOp) { \
  507. LLVMValueRef left = this->compileExpression(builder, *b.fLeft); \
  508. LLVMValueRef right = this->compileExpression(builder, *b.fRight); \
  509. this->vectorize(builder, b, &left, &right); \
  510. switch (this->typeKind(b.fLeft->fType)) { \
  511. case kInt_TypeKind: \
  512. return SFunc(builder, SOp, left, right, "binary"); \
  513. case kUInt_TypeKind: \
  514. return UFunc(builder, UOp, left, right, "binary"); \
  515. case kFloat_TypeKind: \
  516. return FFunc(builder, FOp, left, right, "binary"); \
  517. default: \
  518. ABORT("unsupported typeKind"); \
  519. } \
  520. }
  521. switch (b.fOperator) {
  522. case Token::EQ: {
  523. std::unique_ptr<LValue> lvalue = this->getLValue(builder, *b.fLeft);
  524. LLVMValueRef result = this->compileExpression(builder, *b.fRight);
  525. lvalue->store(builder, result);
  526. return result;
  527. }
  528. case Token::PLUS:
  529. BINARY(LLVMBuildAdd, LLVMBuildAdd, LLVMBuildFAdd);
  530. case Token::MINUS:
  531. BINARY(LLVMBuildSub, LLVMBuildSub, LLVMBuildFSub);
  532. case Token::STAR:
  533. BINARY(LLVMBuildMul, LLVMBuildMul, LLVMBuildFMul);
  534. case Token::SLASH:
  535. BINARY(LLVMBuildSDiv, LLVMBuildUDiv, LLVMBuildFDiv);
  536. case Token::PERCENT:
  537. BINARY(LLVMBuildSRem, LLVMBuildURem, LLVMBuildSRem);
  538. case Token::BITWISEAND:
  539. BINARY(LLVMBuildAnd, LLVMBuildAnd, LLVMBuildAnd);
  540. case Token::BITWISEOR:
  541. BINARY(LLVMBuildOr, LLVMBuildOr, LLVMBuildOr);
  542. case Token::SHL:
  543. BINARY(LLVMBuildShl, LLVMBuildShl, LLVMBuildShl);
  544. case Token::SHR:
  545. BINARY(LLVMBuildAShr, LLVMBuildLShr, LLVMBuildAShr);
  546. case Token::PLUSEQ:
  547. COMPOUND(LLVMBuildAdd, LLVMBuildAdd, LLVMBuildFAdd);
  548. case Token::MINUSEQ:
  549. COMPOUND(LLVMBuildSub, LLVMBuildSub, LLVMBuildFSub);
  550. case Token::STAREQ:
  551. COMPOUND(LLVMBuildMul, LLVMBuildMul, LLVMBuildFMul);
  552. case Token::SLASHEQ:
  553. COMPOUND(LLVMBuildSDiv, LLVMBuildUDiv, LLVMBuildFDiv);
  554. case Token::BITWISEANDEQ:
  555. COMPOUND(LLVMBuildAnd, LLVMBuildAnd, LLVMBuildAnd);
  556. case Token::BITWISEOREQ:
  557. COMPOUND(LLVMBuildOr, LLVMBuildOr, LLVMBuildOr);
  558. case Token::EQEQ:
  559. switch (b.fLeft->fType.kind()) {
  560. case Type::kScalar_Kind:
  561. COMPARE(LLVMBuildICmp, LLVMIntEQ,
  562. LLVMBuildICmp, LLVMIntEQ,
  563. LLVMBuildFCmp, LLVMRealOEQ);
  564. case Type::kVector_Kind: {
  565. LLVMValueRef left = this->compileExpression(builder, *b.fLeft);
  566. LLVMValueRef right = this->compileExpression(builder, *b.fRight);
  567. this->vectorize(builder, b, &left, &right);
  568. LLVMValueRef value;
  569. switch (this->typeKind(b.fLeft->fType)) {
  570. case kInt_TypeKind:
  571. value = LLVMBuildICmp(builder, LLVMIntEQ, left, right, "binary");
  572. break;
  573. case kUInt_TypeKind:
  574. value = LLVMBuildICmp(builder, LLVMIntEQ, left, right, "binary");
  575. break;
  576. case kFloat_TypeKind:
  577. value = LLVMBuildFCmp(builder, LLVMRealOEQ, left, right, "binary");
  578. break;
  579. default:
  580. ABORT("unsupported typeKind");
  581. }
  582. LLVMValueRef args[1] = { value };
  583. LLVMValueRef func;
  584. switch (b.fLeft->fType.columns()) {
  585. case 2: func = fFoldAnd2Func; break;
  586. case 3: func = fFoldAnd3Func; break;
  587. case 4: func = fFoldAnd4Func; break;
  588. default:
  589. SkASSERT(false);
  590. func = fFoldAnd2Func;
  591. }
  592. return LLVMBuildCall(builder, func, args, 1, "all");
  593. }
  594. default:
  595. SkASSERT(false);
  596. }
  597. case Token::NEQ:
  598. switch (b.fLeft->fType.kind()) {
  599. case Type::kScalar_Kind:
  600. COMPARE(LLVMBuildICmp, LLVMIntNE,
  601. LLVMBuildICmp, LLVMIntNE,
  602. LLVMBuildFCmp, LLVMRealONE);
  603. case Type::kVector_Kind: {
  604. LLVMValueRef left = this->compileExpression(builder, *b.fLeft);
  605. LLVMValueRef right = this->compileExpression(builder, *b.fRight);
  606. this->vectorize(builder, b, &left, &right);
  607. LLVMValueRef value;
  608. switch (this->typeKind(b.fLeft->fType)) {
  609. case kInt_TypeKind:
  610. value = LLVMBuildICmp(builder, LLVMIntNE, left, right, "binary");
  611. break;
  612. case kUInt_TypeKind:
  613. value = LLVMBuildICmp(builder, LLVMIntNE, left, right, "binary");
  614. break;
  615. case kFloat_TypeKind:
  616. value = LLVMBuildFCmp(builder, LLVMRealONE, left, right, "binary");
  617. break;
  618. default:
  619. ABORT("unsupported typeKind");
  620. }
  621. LLVMValueRef args[1] = { value };
  622. LLVMValueRef func;
  623. switch (b.fLeft->fType.columns()) {
  624. case 2: func = fFoldOr2Func; break;
  625. case 3: func = fFoldOr3Func; break;
  626. case 4: func = fFoldOr4Func; break;
  627. default:
  628. SkASSERT(false);
  629. func = fFoldOr2Func;
  630. }
  631. return LLVMBuildCall(builder, func, args, 1, "all");
  632. }
  633. default:
  634. SkASSERT(false);
  635. }
  636. case Token::LT:
  637. COMPARE(LLVMBuildICmp, LLVMIntSLT,
  638. LLVMBuildICmp, LLVMIntULT,
  639. LLVMBuildFCmp, LLVMRealOLT);
  640. case Token::LTEQ:
  641. COMPARE(LLVMBuildICmp, LLVMIntSLE,
  642. LLVMBuildICmp, LLVMIntULE,
  643. LLVMBuildFCmp, LLVMRealOLE);
  644. case Token::GT:
  645. COMPARE(LLVMBuildICmp, LLVMIntSGT,
  646. LLVMBuildICmp, LLVMIntUGT,
  647. LLVMBuildFCmp, LLVMRealOGT);
  648. case Token::GTEQ:
  649. COMPARE(LLVMBuildICmp, LLVMIntSGE,
  650. LLVMBuildICmp, LLVMIntUGE,
  651. LLVMBuildFCmp, LLVMRealOGE);
  652. case Token::LOGICALAND: {
  653. LLVMValueRef left = this->compileExpression(builder, *b.fLeft);
  654. LLVMBasicBlockRef ifFalse = fCurrentBlock;
  655. LLVMBasicBlockRef ifTrue = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  656. "true && ...");
  657. LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  658. "&& merge");
  659. LLVMBuildCondBr(builder, left, ifTrue, merge);
  660. this->setBlock(builder, ifTrue);
  661. LLVMValueRef right = this->compileExpression(builder, *b.fRight);
  662. LLVMBuildBr(builder, merge);
  663. this->setBlock(builder, merge);
  664. LLVMValueRef phi = LLVMBuildPhi(builder, fInt1Type, "&&");
  665. LLVMValueRef incomingValues[2] = { right, LLVMConstInt(fInt1Type, 0, false) };
  666. LLVMBasicBlockRef incomingBlocks[2] = { ifTrue, ifFalse };
  667. LLVMAddIncoming(phi, incomingValues, incomingBlocks, 2);
  668. return phi;
  669. }
  670. case Token::LOGICALOR: {
  671. LLVMValueRef left = this->compileExpression(builder, *b.fLeft);
  672. LLVMBasicBlockRef ifTrue = fCurrentBlock;
  673. LLVMBasicBlockRef ifFalse = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  674. "false || ...");
  675. LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  676. "|| merge");
  677. LLVMBuildCondBr(builder, left, merge, ifFalse);
  678. this->setBlock(builder, ifFalse);
  679. LLVMValueRef right = this->compileExpression(builder, *b.fRight);
  680. LLVMBuildBr(builder, merge);
  681. this->setBlock(builder, merge);
  682. LLVMValueRef phi = LLVMBuildPhi(builder, fInt1Type, "||");
  683. LLVMValueRef incomingValues[2] = { right, LLVMConstInt(fInt1Type, 1, false) };
  684. LLVMBasicBlockRef incomingBlocks[2] = { ifFalse, ifTrue };
  685. LLVMAddIncoming(phi, incomingValues, incomingBlocks, 2);
  686. return phi;
  687. }
  688. default:
  689. printf("%s\n", b.description().c_str());
  690. ABORT("unsupported binary operator");
  691. }
  692. }
  693. LLVMValueRef JIT::compileIndex(LLVMBuilderRef builder, const IndexExpression& idx) {
  694. LLVMValueRef base = this->compileExpression(builder, *idx.fBase);
  695. LLVMValueRef index = this->compileExpression(builder, *idx.fIndex);
  696. LLVMValueRef ptr = LLVMBuildGEP(builder, base, &index, 1, "index ptr");
  697. return LLVMBuildLoad(builder, ptr, "index load");
  698. }
  699. LLVMValueRef JIT::compilePostfix(LLVMBuilderRef builder, const PostfixExpression& p) {
  700. std::unique_ptr<LValue> lvalue = this->getLValue(builder, *p.fOperand);
  701. LLVMValueRef result = lvalue->load(builder);
  702. LLVMValueRef mod;
  703. LLVMValueRef one = LLVMConstInt(this->getType(p.fType), 1, false);
  704. switch (p.fOperator) {
  705. case Token::PLUSPLUS:
  706. switch (this->typeKind(p.fType)) {
  707. case kInt_TypeKind: // fall through
  708. case kUInt_TypeKind:
  709. mod = LLVMBuildAdd(builder, result, one, "++");
  710. break;
  711. case kFloat_TypeKind:
  712. mod = LLVMBuildFAdd(builder, result, one, "++");
  713. break;
  714. default:
  715. ABORT("unsupported typeKind");
  716. }
  717. break;
  718. case Token::MINUSMINUS:
  719. switch (this->typeKind(p.fType)) {
  720. case kInt_TypeKind: // fall through
  721. case kUInt_TypeKind:
  722. mod = LLVMBuildSub(builder, result, one, "--");
  723. break;
  724. case kFloat_TypeKind:
  725. mod = LLVMBuildFSub(builder, result, one, "--");
  726. break;
  727. default:
  728. ABORT("unsupported typeKind");
  729. }
  730. break;
  731. default:
  732. ABORT("unsupported postfix op");
  733. }
  734. lvalue->store(builder, mod);
  735. return result;
  736. }
  737. LLVMValueRef JIT::compilePrefix(LLVMBuilderRef builder, const PrefixExpression& p) {
  738. LLVMValueRef one = LLVMConstInt(this->getType(p.fType), 1, false);
  739. if (Token::LOGICALNOT == p.fOperator) {
  740. LLVMValueRef base = this->compileExpression(builder, *p.fOperand);
  741. return LLVMBuildXor(builder, base, one, "!");
  742. }
  743. if (Token::MINUS == p.fOperator) {
  744. LLVMValueRef base = this->compileExpression(builder, *p.fOperand);
  745. return LLVMBuildSub(builder, LLVMConstInt(this->getType(p.fType), 0, false), base, "-");
  746. }
  747. std::unique_ptr<LValue> lvalue = this->getLValue(builder, *p.fOperand);
  748. LLVMValueRef raw = lvalue->load(builder);
  749. LLVMValueRef result;
  750. switch (p.fOperator) {
  751. case Token::PLUSPLUS:
  752. switch (this->typeKind(p.fType)) {
  753. case kInt_TypeKind: // fall through
  754. case kUInt_TypeKind:
  755. result = LLVMBuildAdd(builder, raw, one, "++");
  756. break;
  757. case kFloat_TypeKind:
  758. result = LLVMBuildFAdd(builder, raw, one, "++");
  759. break;
  760. default:
  761. ABORT("unsupported typeKind");
  762. }
  763. break;
  764. case Token::MINUSMINUS:
  765. switch (this->typeKind(p.fType)) {
  766. case kInt_TypeKind: // fall through
  767. case kUInt_TypeKind:
  768. result = LLVMBuildSub(builder, raw, one, "--");
  769. break;
  770. case kFloat_TypeKind:
  771. result = LLVMBuildFSub(builder, raw, one, "--");
  772. break;
  773. default:
  774. ABORT("unsupported typeKind");
  775. }
  776. break;
  777. default:
  778. ABORT("unsupported prefix op");
  779. }
  780. lvalue->store(builder, result);
  781. return result;
  782. }
  783. LLVMValueRef JIT::compileVariableReference(LLVMBuilderRef builder, const VariableReference& v) {
  784. const Variable& var = v.fVariable;
  785. if (Variable::kParameter_Storage == var.fStorage &&
  786. !(var.fModifiers.fFlags & Modifiers::kOut_Flag) &&
  787. fPromotedParameters.find(&var) == fPromotedParameters.end()) {
  788. return fVariables[&var];
  789. }
  790. return LLVMBuildLoad(builder, fVariables[&var], String(var.fName).c_str());
  791. }
  792. void JIT::appendStage(LLVMBuilderRef builder, const AppendStage& a) {
  793. SkASSERT(a.fArguments.size() >= 1);
  794. SkASSERT(a.fArguments[0]->fType == *fCompiler.context().fSkRasterPipeline_Type);
  795. LLVMValueRef pipeline = this->compileExpression(builder, *a.fArguments[0]);
  796. LLVMValueRef stage = LLVMConstInt(fInt32Type, a.fStage, 0);
  797. switch (a.fStage) {
  798. case SkRasterPipeline::callback: {
  799. SkASSERT(a.fArguments.size() == 2);
  800. SkASSERT(a.fArguments[1]->fKind == Expression::kFunctionReference_Kind);
  801. const FunctionDeclaration& functionDecl =
  802. *((FunctionReference&) *a.fArguments[1]).fFunctions[0];
  803. bool found = false;
  804. for (const auto& pe : *fProgram) {
  805. if (ProgramElement::kFunction_Kind == pe.fKind) {
  806. const FunctionDefinition& def = (const FunctionDefinition&) pe;
  807. if (&def.fDeclaration == &functionDecl) {
  808. LLVMValueRef fn = this->compileStageFunction(def);
  809. LLVMValueRef args[2] = {
  810. pipeline,
  811. LLVMBuildBitCast(builder, fn, fInt8PtrType, "callback cast")
  812. };
  813. LLVMBuildCall(builder, fAppendCallbackFunc, args, 2, "");
  814. found = true;
  815. break;
  816. }
  817. }
  818. }
  819. SkASSERT(found);
  820. break;
  821. }
  822. default: {
  823. LLVMValueRef ctx;
  824. if (a.fArguments.size() == 2) {
  825. ctx = this->compileExpression(builder, *a.fArguments[1]);
  826. ctx = LLVMBuildBitCast(builder, ctx, fInt8PtrType, "context cast");
  827. } else {
  828. SkASSERT(a.fArguments.size() == 1);
  829. ctx = LLVMConstNull(fInt8PtrType);
  830. }
  831. LLVMValueRef args[3] = {
  832. pipeline,
  833. stage,
  834. ctx
  835. };
  836. LLVMBuildCall(builder, fAppendFunc, args, 3, "");
  837. break;
  838. }
  839. }
  840. }
  841. LLVMValueRef JIT::compileConstructor(LLVMBuilderRef builder, const Constructor& c) {
  842. switch (c.fType.kind()) {
  843. case Type::kScalar_Kind: {
  844. SkASSERT(c.fArguments.size() == 1);
  845. TypeKind from = this->typeKind(c.fArguments[0]->fType);
  846. TypeKind to = this->typeKind(c.fType);
  847. LLVMValueRef base = this->compileExpression(builder, *c.fArguments[0]);
  848. switch (to) {
  849. case kFloat_TypeKind:
  850. switch (from) {
  851. case kInt_TypeKind:
  852. return LLVMBuildSIToFP(builder, base, this->getType(c.fType), "cast");
  853. case kUInt_TypeKind:
  854. return LLVMBuildUIToFP(builder, base, this->getType(c.fType), "cast");
  855. case kFloat_TypeKind:
  856. return base;
  857. case kBool_TypeKind:
  858. SkASSERT(false);
  859. }
  860. case kInt_TypeKind:
  861. switch (from) {
  862. case kInt_TypeKind:
  863. return base;
  864. case kUInt_TypeKind:
  865. return base;
  866. case kFloat_TypeKind:
  867. return LLVMBuildFPToSI(builder, base, this->getType(c.fType), "cast");
  868. case kBool_TypeKind:
  869. SkASSERT(false);
  870. }
  871. case kUInt_TypeKind:
  872. switch (from) {
  873. case kInt_TypeKind:
  874. return base;
  875. case kUInt_TypeKind:
  876. return base;
  877. case kFloat_TypeKind:
  878. return LLVMBuildFPToUI(builder, base, this->getType(c.fType), "cast");
  879. case kBool_TypeKind:
  880. SkASSERT(false);
  881. }
  882. case kBool_TypeKind:
  883. SkASSERT(false);
  884. }
  885. }
  886. case Type::kVector_Kind: {
  887. LLVMValueRef vec = LLVMGetUndef(this->getType(c.fType));
  888. if (c.fArguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kScalar_Kind) {
  889. LLVMValueRef value = this->compileExpression(builder, *c.fArguments[0]);
  890. for (int i = 0; i < c.fType.columns(); ++i) {
  891. vec = LLVMBuildInsertElement(builder, vec, value,
  892. LLVMConstInt(fInt32Type, i, false),
  893. "vec build 1");
  894. }
  895. } else {
  896. int index = 0;
  897. for (const auto& arg : c.fArguments) {
  898. LLVMValueRef value = this->compileExpression(builder, *arg);
  899. if (arg->fType.kind() == Type::kVector_Kind) {
  900. for (int i = 0; i < arg->fType.columns(); ++i) {
  901. LLVMValueRef column = LLVMBuildExtractElement(builder,
  902. vec,
  903. LLVMConstInt(fInt32Type,
  904. i,
  905. false),
  906. "construct extract");
  907. vec = LLVMBuildInsertElement(builder, vec, column,
  908. LLVMConstInt(fInt32Type, index++, false),
  909. "vec build 2");
  910. }
  911. } else {
  912. vec = LLVMBuildInsertElement(builder, vec, value,
  913. LLVMConstInt(fInt32Type, index++, false),
  914. "vec build 3");
  915. }
  916. }
  917. }
  918. return vec;
  919. }
  920. default:
  921. break;
  922. }
  923. ABORT("unsupported constructor");
  924. }
  925. LLVMValueRef JIT::compileSwizzle(LLVMBuilderRef builder, const Swizzle& s) {
  926. LLVMValueRef base = this->compileExpression(builder, *s.fBase);
  927. if (s.fComponents.size() > 1) {
  928. LLVMValueRef result = LLVMGetUndef(this->getType(s.fType));
  929. for (size_t i = 0; i < s.fComponents.size(); ++i) {
  930. LLVMValueRef element = LLVMBuildExtractElement(
  931. builder,
  932. base,
  933. LLVMConstInt(fInt32Type,
  934. s.fComponents[i],
  935. false),
  936. "swizzle extract");
  937. result = LLVMBuildInsertElement(builder, result, element,
  938. LLVMConstInt(fInt32Type, i, false),
  939. "swizzle insert");
  940. }
  941. return result;
  942. }
  943. SkASSERT(s.fComponents.size() == 1);
  944. return LLVMBuildExtractElement(builder, base,
  945. LLVMConstInt(fInt32Type,
  946. s.fComponents[0],
  947. false),
  948. "swizzle extract");
  949. }
  950. LLVMValueRef JIT::compileTernary(LLVMBuilderRef builder, const TernaryExpression& t) {
  951. LLVMValueRef test = this->compileExpression(builder, *t.fTest);
  952. LLVMBasicBlockRef trueBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  953. "if true");
  954. LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  955. "if merge");
  956. LLVMBasicBlockRef falseBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  957. "if false");
  958. LLVMBuildCondBr(builder, test, trueBlock, falseBlock);
  959. this->setBlock(builder, trueBlock);
  960. LLVMValueRef ifTrue = this->compileExpression(builder, *t.fIfTrue);
  961. trueBlock = fCurrentBlock;
  962. LLVMBuildBr(builder, merge);
  963. this->setBlock(builder, falseBlock);
  964. LLVMValueRef ifFalse = this->compileExpression(builder, *t.fIfFalse);
  965. falseBlock = fCurrentBlock;
  966. LLVMBuildBr(builder, merge);
  967. this->setBlock(builder, merge);
  968. LLVMValueRef phi = LLVMBuildPhi(builder, this->getType(t.fType), "?");
  969. LLVMValueRef incomingValues[2] = { ifTrue, ifFalse };
  970. LLVMBasicBlockRef incomingBlocks[2] = { trueBlock, falseBlock };
  971. LLVMAddIncoming(phi, incomingValues, incomingBlocks, 2);
  972. return phi;
  973. }
  974. LLVMValueRef JIT::compileExpression(LLVMBuilderRef builder, const Expression& expr) {
  975. switch (expr.fKind) {
  976. case Expression::kAppendStage_Kind: {
  977. this->appendStage(builder, (const AppendStage&) expr);
  978. return LLVMValueRef();
  979. }
  980. case Expression::kBinary_Kind:
  981. return this->compileBinary(builder, (BinaryExpression&) expr);
  982. case Expression::kBoolLiteral_Kind:
  983. return LLVMConstInt(fInt1Type, ((BoolLiteral&) expr).fValue, false);
  984. case Expression::kConstructor_Kind:
  985. return this->compileConstructor(builder, (Constructor&) expr);
  986. case Expression::kIntLiteral_Kind:
  987. return LLVMConstInt(this->getType(expr.fType), ((IntLiteral&) expr).fValue, true);
  988. case Expression::kFieldAccess_Kind:
  989. abort();
  990. case Expression::kFloatLiteral_Kind:
  991. return LLVMConstReal(this->getType(expr.fType), ((FloatLiteral&) expr).fValue);
  992. case Expression::kFunctionCall_Kind:
  993. return this->compileFunctionCall(builder, (FunctionCall&) expr);
  994. case Expression::kIndex_Kind:
  995. return this->compileIndex(builder, (IndexExpression&) expr);
  996. case Expression::kPrefix_Kind:
  997. return this->compilePrefix(builder, (PrefixExpression&) expr);
  998. case Expression::kPostfix_Kind:
  999. return this->compilePostfix(builder, (PostfixExpression&) expr);
  1000. case Expression::kSetting_Kind:
  1001. abort();
  1002. case Expression::kSwizzle_Kind:
  1003. return this->compileSwizzle(builder, (Swizzle&) expr);
  1004. case Expression::kVariableReference_Kind:
  1005. return this->compileVariableReference(builder, (VariableReference&) expr);
  1006. case Expression::kTernary_Kind:
  1007. return this->compileTernary(builder, (TernaryExpression&) expr);
  1008. case Expression::kTypeReference_Kind:
  1009. abort();
  1010. default:
  1011. abort();
  1012. }
  1013. ABORT("unsupported expression: %s\n", expr.description().c_str());
  1014. }
  1015. void JIT::compileBlock(LLVMBuilderRef builder, const Block& block) {
  1016. for (const auto& stmt : block.fStatements) {
  1017. this->compileStatement(builder, *stmt);
  1018. }
  1019. }
  1020. void JIT::compileVarDeclarations(LLVMBuilderRef builder, const VarDeclarationsStatement& decls) {
  1021. for (const auto& declStatement : decls.fDeclaration->fVars) {
  1022. const VarDeclaration& decl = (VarDeclaration&) *declStatement;
  1023. LLVMPositionBuilderAtEnd(builder, fAllocaBlock);
  1024. LLVMValueRef alloca = LLVMBuildAlloca(builder, this->getType(decl.fVar->fType),
  1025. String(decl.fVar->fName).c_str());
  1026. fVariables[decl.fVar] = alloca;
  1027. LLVMPositionBuilderAtEnd(builder, fCurrentBlock);
  1028. if (decl.fValue) {
  1029. LLVMValueRef result = this->compileExpression(builder, *decl.fValue);
  1030. LLVMBuildStore(builder, result, alloca);
  1031. }
  1032. }
  1033. }
  1034. void JIT::compileIf(LLVMBuilderRef builder, const IfStatement& i) {
  1035. LLVMValueRef test = this->compileExpression(builder, *i.fTest);
  1036. LLVMBasicBlockRef ifTrue = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "if true");
  1037. LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1038. "if merge");
  1039. LLVMBasicBlockRef ifFalse;
  1040. if (i.fIfFalse) {
  1041. ifFalse = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "if false");
  1042. } else {
  1043. ifFalse = merge;
  1044. }
  1045. LLVMBuildCondBr(builder, test, ifTrue, ifFalse);
  1046. this->setBlock(builder, ifTrue);
  1047. this->compileStatement(builder, *i.fIfTrue);
  1048. if (!ends_with_branch(*i.fIfTrue)) {
  1049. LLVMBuildBr(builder, merge);
  1050. }
  1051. if (i.fIfFalse) {
  1052. this->setBlock(builder, ifFalse);
  1053. this->compileStatement(builder, *i.fIfFalse);
  1054. if (!ends_with_branch(*i.fIfFalse)) {
  1055. LLVMBuildBr(builder, merge);
  1056. }
  1057. }
  1058. this->setBlock(builder, merge);
  1059. }
  1060. void JIT::compileFor(LLVMBuilderRef builder, const ForStatement& f) {
  1061. if (f.fInitializer) {
  1062. this->compileStatement(builder, *f.fInitializer);
  1063. }
  1064. LLVMBasicBlockRef start;
  1065. LLVMBasicBlockRef body = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "for body");
  1066. LLVMBasicBlockRef next = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "for next");
  1067. LLVMBasicBlockRef end = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "for end");
  1068. if (f.fTest) {
  1069. start = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "for test");
  1070. LLVMBuildBr(builder, start);
  1071. this->setBlock(builder, start);
  1072. LLVMValueRef test = this->compileExpression(builder, *f.fTest);
  1073. LLVMBuildCondBr(builder, test, body, end);
  1074. } else {
  1075. start = body;
  1076. LLVMBuildBr(builder, body);
  1077. }
  1078. this->setBlock(builder, body);
  1079. fBreakTarget.push_back(end);
  1080. fContinueTarget.push_back(next);
  1081. this->compileStatement(builder, *f.fStatement);
  1082. fBreakTarget.pop_back();
  1083. fContinueTarget.pop_back();
  1084. if (!ends_with_branch(*f.fStatement)) {
  1085. LLVMBuildBr(builder, next);
  1086. }
  1087. this->setBlock(builder, next);
  1088. if (f.fNext) {
  1089. this->compileExpression(builder, *f.fNext);
  1090. }
  1091. LLVMBuildBr(builder, start);
  1092. this->setBlock(builder, end);
  1093. }
  1094. void JIT::compileDo(LLVMBuilderRef builder, const DoStatement& d) {
  1095. LLVMBasicBlockRef testBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1096. "do test");
  1097. LLVMBasicBlockRef body = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1098. "do body");
  1099. LLVMBasicBlockRef end = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1100. "do end");
  1101. LLVMBuildBr(builder, body);
  1102. this->setBlock(builder, testBlock);
  1103. LLVMValueRef test = this->compileExpression(builder, *d.fTest);
  1104. LLVMBuildCondBr(builder, test, body, end);
  1105. this->setBlock(builder, body);
  1106. fBreakTarget.push_back(end);
  1107. fContinueTarget.push_back(body);
  1108. this->compileStatement(builder, *d.fStatement);
  1109. fBreakTarget.pop_back();
  1110. fContinueTarget.pop_back();
  1111. if (!ends_with_branch(*d.fStatement)) {
  1112. LLVMBuildBr(builder, testBlock);
  1113. }
  1114. this->setBlock(builder, end);
  1115. }
  1116. void JIT::compileWhile(LLVMBuilderRef builder, const WhileStatement& w) {
  1117. LLVMBasicBlockRef testBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1118. "while test");
  1119. LLVMBasicBlockRef body = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1120. "while body");
  1121. LLVMBasicBlockRef end = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction,
  1122. "while end");
  1123. LLVMBuildBr(builder, testBlock);
  1124. this->setBlock(builder, testBlock);
  1125. LLVMValueRef test = this->compileExpression(builder, *w.fTest);
  1126. LLVMBuildCondBr(builder, test, body, end);
  1127. this->setBlock(builder, body);
  1128. fBreakTarget.push_back(end);
  1129. fContinueTarget.push_back(testBlock);
  1130. this->compileStatement(builder, *w.fStatement);
  1131. fBreakTarget.pop_back();
  1132. fContinueTarget.pop_back();
  1133. if (!ends_with_branch(*w.fStatement)) {
  1134. LLVMBuildBr(builder, testBlock);
  1135. }
  1136. this->setBlock(builder, end);
  1137. }
  1138. void JIT::compileBreak(LLVMBuilderRef builder, const BreakStatement& b) {
  1139. LLVMBuildBr(builder, fBreakTarget.back());
  1140. }
  1141. void JIT::compileContinue(LLVMBuilderRef builder, const ContinueStatement& b) {
  1142. LLVMBuildBr(builder, fContinueTarget.back());
  1143. }
  1144. void JIT::compileReturn(LLVMBuilderRef builder, const ReturnStatement& r) {
  1145. if (r.fExpression) {
  1146. LLVMBuildRet(builder, this->compileExpression(builder, *r.fExpression));
  1147. } else {
  1148. LLVMBuildRetVoid(builder);
  1149. }
  1150. }
  1151. void JIT::compileStatement(LLVMBuilderRef builder, const Statement& stmt) {
  1152. switch (stmt.fKind) {
  1153. case Statement::kBlock_Kind:
  1154. this->compileBlock(builder, (Block&) stmt);
  1155. break;
  1156. case Statement::kBreak_Kind:
  1157. this->compileBreak(builder, (BreakStatement&) stmt);
  1158. break;
  1159. case Statement::kContinue_Kind:
  1160. this->compileContinue(builder, (ContinueStatement&) stmt);
  1161. break;
  1162. case Statement::kDiscard_Kind:
  1163. abort();
  1164. case Statement::kDo_Kind:
  1165. this->compileDo(builder, (DoStatement&) stmt);
  1166. break;
  1167. case Statement::kExpression_Kind:
  1168. this->compileExpression(builder, *((ExpressionStatement&) stmt).fExpression);
  1169. break;
  1170. case Statement::kFor_Kind:
  1171. this->compileFor(builder, (ForStatement&) stmt);
  1172. break;
  1173. case Statement::kGroup_Kind:
  1174. abort();
  1175. case Statement::kIf_Kind:
  1176. this->compileIf(builder, (IfStatement&) stmt);
  1177. break;
  1178. case Statement::kNop_Kind:
  1179. break;
  1180. case Statement::kReturn_Kind:
  1181. this->compileReturn(builder, (ReturnStatement&) stmt);
  1182. break;
  1183. case Statement::kSwitch_Kind:
  1184. abort();
  1185. case Statement::kVarDeclarations_Kind:
  1186. this->compileVarDeclarations(builder, (VarDeclarationsStatement&) stmt);
  1187. break;
  1188. case Statement::kWhile_Kind:
  1189. this->compileWhile(builder, (WhileStatement&) stmt);
  1190. break;
  1191. default:
  1192. abort();
  1193. }
  1194. }
  1195. void JIT::compileStageFunctionLoop(const FunctionDefinition& f, LLVMValueRef newFunc) {
  1196. // loop over fVectorCount pixels, running the body of the stage function for each of them
  1197. LLVMValueRef oldFunction = fCurrentFunction;
  1198. fCurrentFunction = newFunc;
  1199. std::unique_ptr<LLVMValueRef[]> params(new LLVMValueRef[STAGE_PARAM_COUNT]);
  1200. LLVMGetParams(fCurrentFunction, params.get());
  1201. LLVMValueRef programParam = params.get()[1];
  1202. LLVMBuilderRef builder = LLVMCreateBuilderInContext(fContext);
  1203. LLVMBasicBlockRef oldAllocaBlock = fAllocaBlock;
  1204. LLVMBasicBlockRef oldCurrentBlock = fCurrentBlock;
  1205. fAllocaBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "alloca");
  1206. this->setBlock(builder, fAllocaBlock);
  1207. // temporaries to store the color channel vectors
  1208. LLVMValueRef rVec = LLVMBuildAlloca(builder, fFloat32VectorType, "rVec");
  1209. LLVMBuildStore(builder, params.get()[4], rVec);
  1210. LLVMValueRef gVec = LLVMBuildAlloca(builder, fFloat32VectorType, "gVec");
  1211. LLVMBuildStore(builder, params.get()[5], gVec);
  1212. LLVMValueRef bVec = LLVMBuildAlloca(builder, fFloat32VectorType, "bVec");
  1213. LLVMBuildStore(builder, params.get()[6], bVec);
  1214. LLVMValueRef aVec = LLVMBuildAlloca(builder, fFloat32VectorType, "aVec");
  1215. LLVMBuildStore(builder, params.get()[7], aVec);
  1216. LLVMValueRef color = LLVMBuildAlloca(builder, fFloat32Vector4Type, "color");
  1217. fVariables[f.fDeclaration.fParameters[1]] = LLVMBuildTrunc(builder, params.get()[3], fInt32Type,
  1218. "y->Int32");
  1219. fVariables[f.fDeclaration.fParameters[2]] = color;
  1220. LLVMValueRef ivar = LLVMBuildAlloca(builder, fInt32Type, "i");
  1221. LLVMBuildStore(builder, LLVMConstInt(fInt32Type, 0, false), ivar);
  1222. LLVMBasicBlockRef start = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "start");
  1223. this->setBlock(builder, start);
  1224. LLVMValueRef iload = LLVMBuildLoad(builder, ivar, "load i");
  1225. fVariables[f.fDeclaration.fParameters[0]] = LLVMBuildAdd(builder,
  1226. LLVMBuildTrunc(builder,
  1227. params.get()[2],
  1228. fInt32Type,
  1229. "x->Int32"),
  1230. iload,
  1231. "x");
  1232. LLVMValueRef vectorSize = LLVMConstInt(fInt32Type, fVectorCount, false);
  1233. LLVMValueRef test = LLVMBuildICmp(builder, LLVMIntSLT, iload, vectorSize, "i < vectorSize");
  1234. LLVMBasicBlockRef loopBody = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "body");
  1235. LLVMBasicBlockRef loopEnd = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "end");
  1236. LLVMBuildCondBr(builder, test, loopBody, loopEnd);
  1237. this->setBlock(builder, loopBody);
  1238. LLVMValueRef vec = LLVMGetUndef(fFloat32Vector4Type);
  1239. // extract the r, g, b, and a values from the color channel vectors and store them into "color"
  1240. for (int i = 0; i < 4; ++i) {
  1241. vec = LLVMBuildInsertElement(builder, vec,
  1242. LLVMBuildExtractElement(builder,
  1243. params.get()[4 + i],
  1244. iload, "initial"),
  1245. LLVMConstInt(fInt32Type, i, false),
  1246. "vec build");
  1247. }
  1248. LLVMBuildStore(builder, vec, color);
  1249. // write actual loop body
  1250. this->compileStatement(builder, *f.fBody);
  1251. // extract the r, g, b, and a values from "color" and stick them back into the color channel
  1252. // vectors
  1253. LLVMValueRef colorLoad = LLVMBuildLoad(builder, color, "color load");
  1254. LLVMBuildStore(builder,
  1255. LLVMBuildInsertElement(builder, LLVMBuildLoad(builder, rVec, "rVec"),
  1256. LLVMBuildExtractElement(builder, colorLoad,
  1257. LLVMConstInt(fInt32Type, 0,
  1258. false),
  1259. "rExtract"),
  1260. iload, "rInsert"),
  1261. rVec);
  1262. LLVMBuildStore(builder,
  1263. LLVMBuildInsertElement(builder, LLVMBuildLoad(builder, gVec, "gVec"),
  1264. LLVMBuildExtractElement(builder, colorLoad,
  1265. LLVMConstInt(fInt32Type, 1,
  1266. false),
  1267. "gExtract"),
  1268. iload, "gInsert"),
  1269. gVec);
  1270. LLVMBuildStore(builder,
  1271. LLVMBuildInsertElement(builder, LLVMBuildLoad(builder, bVec, "bVec"),
  1272. LLVMBuildExtractElement(builder, colorLoad,
  1273. LLVMConstInt(fInt32Type, 2,
  1274. false),
  1275. "bExtract"),
  1276. iload, "bInsert"),
  1277. bVec);
  1278. LLVMBuildStore(builder,
  1279. LLVMBuildInsertElement(builder, LLVMBuildLoad(builder, aVec, "aVec"),
  1280. LLVMBuildExtractElement(builder, colorLoad,
  1281. LLVMConstInt(fInt32Type, 3,
  1282. false),
  1283. "aExtract"),
  1284. iload, "aInsert"),
  1285. aVec);
  1286. LLVMValueRef inc = LLVMBuildAdd(builder, iload, LLVMConstInt(fInt32Type, 1, false), "inc i");
  1287. LLVMBuildStore(builder, inc, ivar);
  1288. LLVMBuildBr(builder, start);
  1289. this->setBlock(builder, loopEnd);
  1290. // increment program pointer, call the next stage
  1291. LLVMValueRef rawNextPtr = LLVMBuildLoad(builder, programParam, "next load");
  1292. LLVMTypeRef stageFuncType = LLVMTypeOf(newFunc);
  1293. LLVMValueRef nextPtr = LLVMBuildBitCast(builder, rawNextPtr, stageFuncType, "cast next->func");
  1294. LLVMValueRef nextInc = LLVMBuildIntToPtr(builder,
  1295. LLVMBuildAdd(builder,
  1296. LLVMBuildPtrToInt(builder,
  1297. programParam,
  1298. fInt64Type,
  1299. "cast 1"),
  1300. LLVMConstInt(fInt64Type, PTR_SIZE, false),
  1301. "add"),
  1302. LLVMPointerType(fInt8PtrType, 0), "cast 2");
  1303. LLVMValueRef args[STAGE_PARAM_COUNT] = {
  1304. params.get()[0],
  1305. nextInc,
  1306. params.get()[2],
  1307. params.get()[3],
  1308. LLVMBuildLoad(builder, rVec, "rVec"),
  1309. LLVMBuildLoad(builder, gVec, "gVec"),
  1310. LLVMBuildLoad(builder, bVec, "bVec"),
  1311. LLVMBuildLoad(builder, aVec, "aVec"),
  1312. params.get()[8],
  1313. params.get()[9],
  1314. params.get()[10],
  1315. params.get()[11]
  1316. };
  1317. LLVMBuildCall(builder, nextPtr, args, STAGE_PARAM_COUNT, "");
  1318. LLVMBuildRetVoid(builder);
  1319. // finish
  1320. LLVMPositionBuilderAtEnd(builder, fAllocaBlock);
  1321. LLVMBuildBr(builder, start);
  1322. LLVMDisposeBuilder(builder);
  1323. if (LLVMVerifyFunction(fCurrentFunction, LLVMPrintMessageAction)) {
  1324. ABORT("verify failed\n");
  1325. }
  1326. fAllocaBlock = oldAllocaBlock;
  1327. fCurrentBlock = oldCurrentBlock;
  1328. fCurrentFunction = oldFunction;
  1329. }
  1330. // FIXME maybe pluggable code generators? Need to do something to separate all
  1331. // of the normal codegen from the vector codegen and break this up into multiple
  1332. // classes.
  1333. bool JIT::getVectorLValue(LLVMBuilderRef builder, const Expression& e,
  1334. LLVMValueRef out[CHANNELS]) {
  1335. switch (e.fKind) {
  1336. case Expression::kVariableReference_Kind:
  1337. if (fColorParam == &((VariableReference&) e).fVariable) {
  1338. memcpy(out, fChannels, sizeof(fChannels));
  1339. return true;
  1340. }
  1341. return false;
  1342. case Expression::kSwizzle_Kind: {
  1343. const Swizzle& s = (const Swizzle&) e;
  1344. LLVMValueRef base[CHANNELS];
  1345. if (!this->getVectorLValue(builder, *s.fBase, base)) {
  1346. return false;
  1347. }
  1348. for (size_t i = 0; i < s.fComponents.size(); ++i) {
  1349. out[i] = base[s.fComponents[i]];
  1350. }
  1351. return true;
  1352. }
  1353. default:
  1354. return false;
  1355. }
  1356. }
  1357. bool JIT::getVectorBinaryOperands(LLVMBuilderRef builder, const Expression& left,
  1358. LLVMValueRef outLeft[CHANNELS], const Expression& right,
  1359. LLVMValueRef outRight[CHANNELS]) {
  1360. if (!this->compileVectorExpression(builder, left, outLeft)) {
  1361. return false;
  1362. }
  1363. int leftColumns = left.fType.columns();
  1364. int rightColumns = right.fType.columns();
  1365. if (leftColumns == 1 && rightColumns > 1) {
  1366. for (int i = 1; i < rightColumns; ++i) {
  1367. outLeft[i] = outLeft[0];
  1368. }
  1369. }
  1370. if (!this->compileVectorExpression(builder, right, outRight)) {
  1371. return false;
  1372. }
  1373. if (rightColumns == 1 && leftColumns > 1) {
  1374. for (int i = 1; i < leftColumns; ++i) {
  1375. outRight[i] = outRight[0];
  1376. }
  1377. }
  1378. return true;
  1379. }
  1380. bool JIT::compileVectorBinary(LLVMBuilderRef builder, const BinaryExpression& b,
  1381. LLVMValueRef out[CHANNELS]) {
  1382. LLVMValueRef left[CHANNELS];
  1383. LLVMValueRef right[CHANNELS];
  1384. #define VECTOR_BINARY(signedOp, unsignedOp, floatOp) { \
  1385. if (!this->getVectorBinaryOperands(builder, *b.fLeft, left, *b.fRight, right)) { \
  1386. return false; \
  1387. } \
  1388. for (int i = 0; i < b.fLeft->fType.columns(); ++i) { \
  1389. switch (this->typeKind(b.fLeft->fType)) { \
  1390. case kInt_TypeKind: \
  1391. out[i] = signedOp(builder, left[i], right[i], "binary"); \
  1392. break; \
  1393. case kUInt_TypeKind: \
  1394. out[i] = unsignedOp(builder, left[i], right[i], "binary"); \
  1395. break; \
  1396. case kFloat_TypeKind: \
  1397. out[i] = floatOp(builder, left[i], right[i], "binary"); \
  1398. break; \
  1399. case kBool_TypeKind: \
  1400. SkASSERT(false); \
  1401. break; \
  1402. } \
  1403. } \
  1404. return true; \
  1405. }
  1406. switch (b.fOperator) {
  1407. case Token::EQ: {
  1408. if (!this->getVectorLValue(builder, *b.fLeft, left)) {
  1409. return false;
  1410. }
  1411. if (!this->compileVectorExpression(builder, *b.fRight, right)) {
  1412. return false;
  1413. }
  1414. int columns = b.fRight->fType.columns();
  1415. for (int i = 0; i < columns; ++i) {
  1416. LLVMBuildStore(builder, right[i], left[i]);
  1417. }
  1418. return true;
  1419. }
  1420. case Token::PLUS:
  1421. VECTOR_BINARY(LLVMBuildAdd, LLVMBuildAdd, LLVMBuildFAdd);
  1422. case Token::MINUS:
  1423. VECTOR_BINARY(LLVMBuildSub, LLVMBuildSub, LLVMBuildFSub);
  1424. case Token::STAR:
  1425. VECTOR_BINARY(LLVMBuildMul, LLVMBuildMul, LLVMBuildFMul);
  1426. case Token::SLASH:
  1427. VECTOR_BINARY(LLVMBuildSDiv, LLVMBuildUDiv, LLVMBuildFDiv);
  1428. case Token::PERCENT:
  1429. VECTOR_BINARY(LLVMBuildSRem, LLVMBuildURem, LLVMBuildSRem);
  1430. case Token::BITWISEAND:
  1431. VECTOR_BINARY(LLVMBuildAnd, LLVMBuildAnd, LLVMBuildAnd);
  1432. case Token::BITWISEOR:
  1433. VECTOR_BINARY(LLVMBuildOr, LLVMBuildOr, LLVMBuildOr);
  1434. default:
  1435. printf("unsupported operator: %s\n", b.description().c_str());
  1436. return false;
  1437. }
  1438. }
  1439. bool JIT::compileVectorConstructor(LLVMBuilderRef builder, const Constructor& c,
  1440. LLVMValueRef out[CHANNELS]) {
  1441. switch (c.fType.kind()) {
  1442. case Type::kScalar_Kind: {
  1443. SkASSERT(c.fArguments.size() == 1);
  1444. TypeKind from = this->typeKind(c.fArguments[0]->fType);
  1445. TypeKind to = this->typeKind(c.fType);
  1446. LLVMValueRef base[CHANNELS];
  1447. if (!this->compileVectorExpression(builder, *c.fArguments[0], base)) {
  1448. return false;
  1449. }
  1450. #define CONSTRUCT(fn) \
  1451. out[0] = LLVMGetUndef(LLVMVectorType(this->getType(c.fType), fVectorCount)); \
  1452. for (int i = 0; i < fVectorCount; ++i) { \
  1453. LLVMValueRef index = LLVMConstInt(fInt32Type, i, false); \
  1454. LLVMValueRef baseVal = LLVMBuildExtractElement(builder, base[0], index, \
  1455. "construct extract"); \
  1456. out[0] = LLVMBuildInsertElement(builder, out[0], \
  1457. fn(builder, baseVal, this->getType(c.fType), \
  1458. "cast"), \
  1459. index, "construct insert"); \
  1460. } \
  1461. return true;
  1462. if (kFloat_TypeKind == to) {
  1463. if (kInt_TypeKind == from) {
  1464. CONSTRUCT(LLVMBuildSIToFP);
  1465. }
  1466. if (kUInt_TypeKind == from) {
  1467. CONSTRUCT(LLVMBuildUIToFP);
  1468. }
  1469. }
  1470. if (kInt_TypeKind == to) {
  1471. if (kFloat_TypeKind == from) {
  1472. CONSTRUCT(LLVMBuildFPToSI);
  1473. }
  1474. if (kUInt_TypeKind == from) {
  1475. return true;
  1476. }
  1477. }
  1478. if (kUInt_TypeKind == to) {
  1479. if (kFloat_TypeKind == from) {
  1480. CONSTRUCT(LLVMBuildFPToUI);
  1481. }
  1482. if (kInt_TypeKind == from) {
  1483. return base;
  1484. }
  1485. }
  1486. printf("%s\n", c.description().c_str());
  1487. ABORT("unsupported constructor");
  1488. }
  1489. case Type::kVector_Kind: {
  1490. if (c.fArguments.size() == 1) {
  1491. LLVMValueRef base[CHANNELS];
  1492. if (!this->compileVectorExpression(builder, *c.fArguments[0], base)) {
  1493. return false;
  1494. }
  1495. for (int i = 0; i < c.fType.columns(); ++i) {
  1496. out[i] = base[0];
  1497. }
  1498. } else {
  1499. SkASSERT(c.fArguments.size() == (size_t) c.fType.columns());
  1500. for (int i = 0; i < c.fType.columns(); ++i) {
  1501. LLVMValueRef base[CHANNELS];
  1502. if (!this->compileVectorExpression(builder, *c.fArguments[i], base)) {
  1503. return false;
  1504. }
  1505. out[i] = base[0];
  1506. }
  1507. }
  1508. return true;
  1509. }
  1510. default:
  1511. break;
  1512. }
  1513. ABORT("unsupported constructor");
  1514. }
  1515. bool JIT::compileVectorFloatLiteral(LLVMBuilderRef builder,
  1516. const FloatLiteral& f,
  1517. LLVMValueRef out[CHANNELS]) {
  1518. LLVMValueRef value = LLVMConstReal(this->getType(f.fType), f.fValue);
  1519. LLVMValueRef values[MAX_VECTOR_COUNT];
  1520. for (int i = 0; i < fVectorCount; ++i) {
  1521. values[i] = value;
  1522. }
  1523. out[0] = LLVMConstVector(values, fVectorCount);
  1524. return true;
  1525. }
  1526. bool JIT::compileVectorSwizzle(LLVMBuilderRef builder, const Swizzle& s,
  1527. LLVMValueRef out[CHANNELS]) {
  1528. LLVMValueRef all[CHANNELS];
  1529. if (!this->compileVectorExpression(builder, *s.fBase, all)) {
  1530. return false;
  1531. }
  1532. for (size_t i = 0; i < s.fComponents.size(); ++i) {
  1533. out[i] = all[s.fComponents[i]];
  1534. }
  1535. return true;
  1536. }
  1537. bool JIT::compileVectorVariableReference(LLVMBuilderRef builder, const VariableReference& v,
  1538. LLVMValueRef out[CHANNELS]) {
  1539. if (&v.fVariable == fColorParam) {
  1540. for (int i = 0; i < CHANNELS; ++i) {
  1541. out[i] = LLVMBuildLoad(builder, fChannels[i], "variable reference");
  1542. }
  1543. return true;
  1544. }
  1545. return false;
  1546. }
  1547. bool JIT::compileVectorExpression(LLVMBuilderRef builder, const Expression& expr,
  1548. LLVMValueRef out[CHANNELS]) {
  1549. switch (expr.fKind) {
  1550. case Expression::kBinary_Kind:
  1551. return this->compileVectorBinary(builder, (const BinaryExpression&) expr, out);
  1552. case Expression::kConstructor_Kind:
  1553. return this->compileVectorConstructor(builder, (const Constructor&) expr, out);
  1554. case Expression::kFloatLiteral_Kind:
  1555. return this->compileVectorFloatLiteral(builder, (const FloatLiteral&) expr, out);
  1556. case Expression::kSwizzle_Kind:
  1557. return this->compileVectorSwizzle(builder, (const Swizzle&) expr, out);
  1558. case Expression::kVariableReference_Kind:
  1559. return this->compileVectorVariableReference(builder, (const VariableReference&) expr,
  1560. out);
  1561. default:
  1562. return false;
  1563. }
  1564. }
  1565. bool JIT::compileVectorStatement(LLVMBuilderRef builder, const Statement& stmt) {
  1566. switch (stmt.fKind) {
  1567. case Statement::kBlock_Kind:
  1568. for (const auto& s : ((const Block&) stmt).fStatements) {
  1569. if (!this->compileVectorStatement(builder, *s)) {
  1570. return false;
  1571. }
  1572. }
  1573. return true;
  1574. case Statement::kExpression_Kind:
  1575. LLVMValueRef result;
  1576. return this->compileVectorExpression(builder,
  1577. *((const ExpressionStatement&) stmt).fExpression,
  1578. &result);
  1579. default:
  1580. return false;
  1581. }
  1582. }
  1583. bool JIT::compileStageFunctionVector(const FunctionDefinition& f, LLVMValueRef newFunc) {
  1584. LLVMValueRef oldFunction = fCurrentFunction;
  1585. fCurrentFunction = newFunc;
  1586. std::unique_ptr<LLVMValueRef[]> params(new LLVMValueRef[STAGE_PARAM_COUNT]);
  1587. LLVMGetParams(fCurrentFunction, params.get());
  1588. LLVMValueRef programParam = params.get()[1];
  1589. LLVMBuilderRef builder = LLVMCreateBuilderInContext(fContext);
  1590. LLVMBasicBlockRef oldAllocaBlock = fAllocaBlock;
  1591. LLVMBasicBlockRef oldCurrentBlock = fCurrentBlock;
  1592. fAllocaBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "alloca");
  1593. this->setBlock(builder, fAllocaBlock);
  1594. fChannels[0] = LLVMBuildAlloca(builder, fFloat32VectorType, "rVec");
  1595. LLVMBuildStore(builder, params.get()[4], fChannels[0]);
  1596. fChannels[1] = LLVMBuildAlloca(builder, fFloat32VectorType, "gVec");
  1597. LLVMBuildStore(builder, params.get()[5], fChannels[1]);
  1598. fChannels[2] = LLVMBuildAlloca(builder, fFloat32VectorType, "bVec");
  1599. LLVMBuildStore(builder, params.get()[6], fChannels[2]);
  1600. fChannels[3] = LLVMBuildAlloca(builder, fFloat32VectorType, "aVec");
  1601. LLVMBuildStore(builder, params.get()[7], fChannels[3]);
  1602. LLVMBasicBlockRef start = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "start");
  1603. this->setBlock(builder, start);
  1604. bool success = this->compileVectorStatement(builder, *f.fBody);
  1605. if (success) {
  1606. // increment program pointer, call next
  1607. LLVMValueRef rawNextPtr = LLVMBuildLoad(builder, programParam, "next load");
  1608. LLVMTypeRef stageFuncType = LLVMTypeOf(newFunc);
  1609. LLVMValueRef nextPtr = LLVMBuildBitCast(builder, rawNextPtr, stageFuncType,
  1610. "cast next->func");
  1611. LLVMValueRef nextInc = LLVMBuildIntToPtr(builder,
  1612. LLVMBuildAdd(builder,
  1613. LLVMBuildPtrToInt(builder,
  1614. programParam,
  1615. fInt64Type,
  1616. "cast 1"),
  1617. LLVMConstInt(fInt64Type, PTR_SIZE,
  1618. false),
  1619. "add"),
  1620. LLVMPointerType(fInt8PtrType, 0), "cast 2");
  1621. LLVMValueRef args[STAGE_PARAM_COUNT] = {
  1622. params.get()[0],
  1623. nextInc,
  1624. params.get()[2],
  1625. params.get()[3],
  1626. LLVMBuildLoad(builder, fChannels[0], "rVec"),
  1627. LLVMBuildLoad(builder, fChannels[1], "gVec"),
  1628. LLVMBuildLoad(builder, fChannels[2], "bVec"),
  1629. LLVMBuildLoad(builder, fChannels[3], "aVec"),
  1630. params.get()[8],
  1631. params.get()[9],
  1632. params.get()[10],
  1633. params.get()[11]
  1634. };
  1635. LLVMBuildCall(builder, nextPtr, args, STAGE_PARAM_COUNT, "");
  1636. LLVMBuildRetVoid(builder);
  1637. // finish
  1638. LLVMPositionBuilderAtEnd(builder, fAllocaBlock);
  1639. LLVMBuildBr(builder, start);
  1640. LLVMDisposeBuilder(builder);
  1641. if (LLVMVerifyFunction(fCurrentFunction, LLVMPrintMessageAction)) {
  1642. ABORT("verify failed\n");
  1643. }
  1644. } else {
  1645. LLVMDeleteBasicBlock(fAllocaBlock);
  1646. LLVMDeleteBasicBlock(start);
  1647. }
  1648. fAllocaBlock = oldAllocaBlock;
  1649. fCurrentBlock = oldCurrentBlock;
  1650. fCurrentFunction = oldFunction;
  1651. return success;
  1652. }
  1653. LLVMValueRef JIT::compileStageFunction(const FunctionDefinition& f) {
  1654. LLVMTypeRef returnType = fVoidType;
  1655. LLVMTypeRef parameterTypes[12] = { fSizeTType, LLVMPointerType(fInt8PtrType, 0), fSizeTType,
  1656. fSizeTType, fFloat32VectorType, fFloat32VectorType,
  1657. fFloat32VectorType, fFloat32VectorType, fFloat32VectorType,
  1658. fFloat32VectorType, fFloat32VectorType, fFloat32VectorType };
  1659. LLVMTypeRef stageFuncType = LLVMFunctionType(returnType, parameterTypes, 12, false);
  1660. LLVMValueRef result = LLVMAddFunction(fModule,
  1661. (String(f.fDeclaration.fName) + "$stage").c_str(),
  1662. stageFuncType);
  1663. fColorParam = f.fDeclaration.fParameters[2];
  1664. if (!this->compileStageFunctionVector(f, result)) {
  1665. // vectorization failed, fall back to looping over the pixels
  1666. this->compileStageFunctionLoop(f, result);
  1667. }
  1668. return result;
  1669. }
  1670. bool JIT::hasStageSignature(const FunctionDeclaration& f) {
  1671. return f.fReturnType == *fProgram->fContext->fVoid_Type &&
  1672. f.fParameters.size() == 3 &&
  1673. f.fParameters[0]->fType == *fProgram->fContext->fInt_Type &&
  1674. f.fParameters[0]->fModifiers.fFlags == 0 &&
  1675. f.fParameters[1]->fType == *fProgram->fContext->fInt_Type &&
  1676. f.fParameters[1]->fModifiers.fFlags == 0 &&
  1677. f.fParameters[2]->fType == *fProgram->fContext->fHalf4_Type &&
  1678. f.fParameters[2]->fModifiers.fFlags == (Modifiers::kIn_Flag | Modifiers::kOut_Flag);
  1679. }
  1680. LLVMValueRef JIT::compileFunction(const FunctionDefinition& f) {
  1681. if (this->hasStageSignature(f.fDeclaration)) {
  1682. this->compileStageFunction(f);
  1683. // we compile foo$stage *in addition* to compiling foo, as we can't be sure that the intent
  1684. // was to produce an SkJumper stage just because the signature matched or that the function
  1685. // is not otherwise called. May need a better way to handle this.
  1686. }
  1687. LLVMTypeRef returnType = this->getType(f.fDeclaration.fReturnType);
  1688. std::vector<LLVMTypeRef> parameterTypes;
  1689. for (const auto& p : f.fDeclaration.fParameters) {
  1690. LLVMTypeRef type = this->getType(p->fType);
  1691. if (p->fModifiers.fFlags & Modifiers::kOut_Flag) {
  1692. type = LLVMPointerType(type, 0);
  1693. }
  1694. parameterTypes.push_back(type);
  1695. }
  1696. fCurrentFunction = LLVMAddFunction(fModule,
  1697. String(f.fDeclaration.fName).c_str(),
  1698. LLVMFunctionType(returnType, parameterTypes.data(),
  1699. parameterTypes.size(), false));
  1700. fFunctions[&f.fDeclaration] = fCurrentFunction;
  1701. std::unique_ptr<LLVMValueRef[]> params(new LLVMValueRef[parameterTypes.size()]);
  1702. LLVMGetParams(fCurrentFunction, params.get());
  1703. for (size_t i = 0; i < f.fDeclaration.fParameters.size(); ++i) {
  1704. fVariables[f.fDeclaration.fParameters[i]] = params.get()[i];
  1705. }
  1706. LLVMBuilderRef builder = LLVMCreateBuilderInContext(fContext);
  1707. fAllocaBlock = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "alloca");
  1708. LLVMBasicBlockRef start = LLVMAppendBasicBlockInContext(fContext, fCurrentFunction, "start");
  1709. fCurrentBlock = start;
  1710. LLVMPositionBuilderAtEnd(builder, fCurrentBlock);
  1711. this->compileStatement(builder, *f.fBody);
  1712. if (!ends_with_branch(*f.fBody)) {
  1713. if (f.fDeclaration.fReturnType == *fProgram->fContext->fVoid_Type) {
  1714. LLVMBuildRetVoid(builder);
  1715. } else {
  1716. LLVMBuildUnreachable(builder);
  1717. }
  1718. }
  1719. LLVMPositionBuilderAtEnd(builder, fAllocaBlock);
  1720. LLVMBuildBr(builder, start);
  1721. LLVMDisposeBuilder(builder);
  1722. if (LLVMVerifyFunction(fCurrentFunction, LLVMPrintMessageAction)) {
  1723. ABORT("verify failed\n");
  1724. }
  1725. return fCurrentFunction;
  1726. }
  1727. void JIT::createModule() {
  1728. fPromotedParameters.clear();
  1729. fModule = LLVMModuleCreateWithNameInContext("skslmodule", fContext);
  1730. this->loadBuiltinFunctions();
  1731. LLVMTypeRef fold2Params[1] = { fInt1Vector2Type };
  1732. fFoldAnd2Func = LLVMAddFunction(fModule, "llvm.experimental.vector.reduce.and.i1.v2i1",
  1733. LLVMFunctionType(fInt1Type, fold2Params, 1, false));
  1734. fFoldOr2Func = LLVMAddFunction(fModule, "llvm.experimental.vector.reduce.or.i1.v2i1",
  1735. LLVMFunctionType(fInt1Type, fold2Params, 1, false));
  1736. LLVMTypeRef fold3Params[1] = { fInt1Vector3Type };
  1737. fFoldAnd3Func = LLVMAddFunction(fModule, "llvm.experimental.vector.reduce.and.i1.v3i1",
  1738. LLVMFunctionType(fInt1Type, fold3Params, 1, false));
  1739. fFoldOr3Func = LLVMAddFunction(fModule, "llvm.experimental.vector.reduce.or.i1.v3i1",
  1740. LLVMFunctionType(fInt1Type, fold3Params, 1, false));
  1741. LLVMTypeRef fold4Params[1] = { fInt1Vector4Type };
  1742. fFoldAnd4Func = LLVMAddFunction(fModule, "llvm.experimental.vector.reduce.and.i1.v4i1",
  1743. LLVMFunctionType(fInt1Type, fold4Params, 1, false));
  1744. fFoldOr4Func = LLVMAddFunction(fModule, "llvm.experimental.vector.reduce.or.i1.v4i1",
  1745. LLVMFunctionType(fInt1Type, fold4Params, 1, false));
  1746. // LLVM doesn't do void*, have to declare it as int8*
  1747. LLVMTypeRef appendParams[3] = { fInt8PtrType, fInt32Type, fInt8PtrType };
  1748. fAppendFunc = LLVMAddFunction(fModule, "sksl_pipeline_append", LLVMFunctionType(fVoidType,
  1749. appendParams,
  1750. 3,
  1751. false));
  1752. LLVMTypeRef appendCallbackParams[2] = { fInt8PtrType, fInt8PtrType };
  1753. fAppendCallbackFunc = LLVMAddFunction(fModule, "sksl_pipeline_append_callback",
  1754. LLVMFunctionType(fVoidType, appendCallbackParams, 2,
  1755. false));
  1756. LLVMTypeRef debugParams[3] = { fFloat32Type };
  1757. fDebugFunc = LLVMAddFunction(fModule, "sksl_debug_print", LLVMFunctionType(fVoidType,
  1758. debugParams,
  1759. 1,
  1760. false));
  1761. for (const auto& e : *fProgram) {
  1762. if (e.fKind == ProgramElement::kFunction_Kind) {
  1763. this->compileFunction((FunctionDefinition&) e);
  1764. }
  1765. }
  1766. }
  1767. std::unique_ptr<JIT::Module> JIT::compile(std::unique_ptr<Program> program) {
  1768. fCompiler.optimize(*program);
  1769. fProgram = std::move(program);
  1770. this->createModule();
  1771. this->optimize();
  1772. return std::unique_ptr<Module>(new Module(std::move(fProgram), fSharedModule, fJITStack));
  1773. }
  1774. void JIT::optimize() {
  1775. LLVMPassManagerBuilderRef pmb = LLVMPassManagerBuilderCreate();
  1776. LLVMPassManagerBuilderSetOptLevel(pmb, 3);
  1777. LLVMPassManagerRef functionPM = LLVMCreateFunctionPassManagerForModule(fModule);
  1778. LLVMPassManagerBuilderPopulateFunctionPassManager(pmb, functionPM);
  1779. LLVMPassManagerRef modulePM = LLVMCreatePassManager();
  1780. LLVMPassManagerBuilderPopulateModulePassManager(pmb, modulePM);
  1781. LLVMInitializeFunctionPassManager(functionPM);
  1782. LLVMValueRef func = LLVMGetFirstFunction(fModule);
  1783. for (;;) {
  1784. if (!func) {
  1785. break;
  1786. }
  1787. LLVMRunFunctionPassManager(functionPM, func);
  1788. func = LLVMGetNextFunction(func);
  1789. }
  1790. LLVMRunPassManager(modulePM, fModule);
  1791. LLVMDisposePassManager(functionPM);
  1792. LLVMDisposePassManager(modulePM);
  1793. LLVMPassManagerBuilderDispose(pmb);
  1794. std::string error_string;
  1795. if (LLVMLoadLibraryPermanently(nullptr)) {
  1796. ABORT("LLVMLoadLibraryPermanently failed");
  1797. }
  1798. char* defaultTriple = LLVMGetDefaultTargetTriple();
  1799. char* error;
  1800. LLVMTargetRef target;
  1801. if (LLVMGetTargetFromTriple(defaultTriple, &target, &error)) {
  1802. ABORT("LLVMGetTargetFromTriple failed");
  1803. }
  1804. if (!LLVMTargetHasJIT(target)) {
  1805. ABORT("!LLVMTargetHasJIT");
  1806. }
  1807. LLVMTargetMachineRef targetMachine = LLVMCreateTargetMachine(target,
  1808. defaultTriple,
  1809. fCPU,
  1810. nullptr,
  1811. LLVMCodeGenLevelDefault,
  1812. LLVMRelocDefault,
  1813. LLVMCodeModelJITDefault);
  1814. LLVMDisposeMessage(defaultTriple);
  1815. LLVMTargetDataRef dataLayout = LLVMCreateTargetDataLayout(targetMachine);
  1816. LLVMSetModuleDataLayout(fModule, dataLayout);
  1817. LLVMDisposeTargetData(dataLayout);
  1818. fJITStack = LLVMOrcCreateInstance(targetMachine);
  1819. fSharedModule = LLVMOrcMakeSharedModule(fModule);
  1820. LLVMOrcModuleHandle orcModule;
  1821. LLVMOrcAddEagerlyCompiledIR(fJITStack, &orcModule, fSharedModule,
  1822. (LLVMOrcSymbolResolverFn) resolveSymbol, this);
  1823. LLVMDisposeTargetMachine(targetMachine);
  1824. }
  1825. void* JIT::Module::getSymbol(const char* name) {
  1826. LLVMOrcTargetAddress result;
  1827. if (LLVMOrcGetSymbolAddress(fJITStack, &result, name)) {
  1828. ABORT("GetSymbolAddress error");
  1829. }
  1830. if (!result) {
  1831. ABORT("symbol not found");
  1832. }
  1833. return (void*) result;
  1834. }
  1835. void* JIT::Module::getJumperStage(const char* name) {
  1836. return this->getSymbol((String(name) + "$stage").c_str());
  1837. }
  1838. } // namespace
  1839. #endif // SK_LLVM_AVAILABLE
  1840. #endif // SKSL_STANDALONE