bool VectorMatMult::buildIL() { // marking all locals as defined allows remaining locals to be temps // which enables further optimization opportunities particularly for // floating point types AllLocalsHaveBeenDefined(); OMR::JitBuilder::IlValue *i, *j, *k; OMR::JitBuilder::IlValue *A_ik, *B_kj; OMR::JitBuilder::IlValue *A = Load("A"); OMR::JitBuilder::IlValue *B = Load("B"); OMR::JitBuilder::IlValue *C = Load("C"); OMR::JitBuilder::IlValue *N = Load("N"); OMR::JitBuilder::IlValue *zero = ConstInt32(0); OMR::JitBuilder::IlValue *one = ConstInt32(1); OMR::JitBuilder::IlValue *two = ConstInt32(2); OMR::JitBuilder::IlBuilder *iloop=NULL, *jloop=NULL, *kloop=NULL; ForLoopUp("i", &iloop, zero, N, one); { i = iloop->Load("i"); // vectorizing loop j iloop->ForLoopUp("j", &jloop, zero, N, two); { j = jloop->Load("j"); jloop->VectorStore("sum", // sum is a vector jloop-> ConstDouble(0.0)); jloop->ForLoopUp("k", &kloop, zero, N, one); { k = kloop->Load("k"); A_ik = Load2D(kloop, A, i, k, N); // A[i,k] is scalar over j B_kj = VectorLoad2D(kloop, B, k, j, N); // B[k,j] is vector over j kloop->VectorStore("sum", kloop-> Add( kloop-> VectorLoad("sum"), kloop-> Mul(A_ik, B_kj))); } VectorStore2D(jloop, C, i, j, N, jloop->Load("sum")); // C[i,j] is vector over j } } Return(); return true; }
bool MatMult::buildIL() { // marking all locals as defined allows remaining locals to be temps // which enables further optimization opportunities particularly for // floating point types AllLocalsHaveBeenDefined(); TR::IlValue *i, *j, *k; TR::IlValue *A_ik, *B_kj; TR::IlValue *A = Load("A"); TR::IlValue *B = Load("B"); TR::IlValue *C = Load("C"); TR::IlValue *N = Load("N"); TR::IlValue *zero = ConstInt32(0); TR::IlValue *one = ConstInt32(1); TR::IlBuilder *iloop=NULL, *jloop=NULL, *kloop=NULL; ForLoopUp("i", &iloop, zero, N, one); { i = iloop->Load("i"); iloop->ForLoopUp("j", &jloop, zero, N, one); { j = jloop->Load("j"); jloop->Store("sum", jloop-> ConstDouble(0.0)); jloop->ForLoopUp("k", &kloop, zero, N, one); { k = kloop->Load("k"); A_ik = Load2D(kloop, A, i, k, N); B_kj = Load2D(kloop, B, k, j, N); kloop->Store("sum", kloop-> Add( kloop-> Load("sum"), kloop-> Mul(A_ik, B_kj))); } Store2D(jloop, C, i, j, N, jloop->Load("sum")); } } Return(); return true; }
bool ThunkBuilder::buildIL() { TR::IlType *pWord = typeDictionary()->PointerTo(Word); uint32_t numArgs = _numCalleeParams+1; TR::IlValue **args = (TR::IlValue **) comp()->trMemory()->allocateHeapMemory(numArgs * sizeof(TR::IlValue *)); // first argument is the target address args[0] = Load("target"); // followed by the actual arguments for (uint32_t p=0; p < _numCalleeParams; p++) { uint32_t a=p+1; args[a] = ConvertTo(_calleeParamTypes[p], LoadAt(pWord, IndexAt(pWord, Load("args"), ConstInt32(p)))); } TR::IlValue *retValue = ComputedCall("thunkCallee", numArgs, args); if (getReturnType() != NoType) Return(retValue); Return(); return true; }
bool DotProduct::buildIL() { PrintString(this, "dotproduct parameters:\n"); PrintString(this, " result is "); Call("printPointer", 1, Load("result")); PrintString(this, "\n"); PrintString(this, " vector1 is "); Call("printPointer", 1, Load("vector1")); PrintString(this, "\n"); PrintString(this, " vector2 is "); Call("printPointer", 1, Load("vector2")); PrintString(this, "\n"); TR::IlBuilder *loop = NULL; ForLoopUp("i", &loop, ConstInt32(0), Load("length"), ConstInt32(1)); loop->StoreAt( loop-> IndexAt(pDouble, loop-> Load("result"), loop-> Load("i")), loop-> Mul( loop-> LoadAt(pDouble, loop-> IndexAt(pDouble, loop-> Load("vector1"), loop-> Load("i"))), loop-> LoadAt(pDouble, loop-> IndexAt(pDouble, loop-> Load("vector2"), loop-> Load("i"))))); Return(); return true; }
bool InliningRecursiveFibonacciMethod::buildIL() { TR::IlBuilder *baseCase=NULL, *recursiveCase=NULL; IfThenElse(&baseCase, &recursiveCase, LessThan( Load("n"), ConstInt32(2))); DefineLocal("result", Int32); baseCase->Store("result", baseCase-> Load("n")); TR::IlValue *nMinusOne = recursiveCase-> Sub( recursiveCase-> Load("n"), recursiveCase-> ConstInt32(1)); TR::IlValue *fib_nMinusOne; if (_inlineDepth > 0) { // memory leak here, but just an example InliningRecursiveFibonacciMethod *inlineFib = new InliningRecursiveFibonacciMethod(this); fib_nMinusOne = recursiveCase->Call(inlineFib, 1, nMinusOne); } else fib_nMinusOne = recursiveCase->Call("fib", 1, nMinusOne); TR::IlValue *nMinusTwo = recursiveCase-> Sub( recursiveCase-> Load("n"), recursiveCase-> ConstInt32(2)); TR::IlValue *fib_nMinusTwo; if (_inlineDepth > 0) { // memory leak here, but just an example InliningRecursiveFibonacciMethod *inlineFib = new InliningRecursiveFibonacciMethod(this); fib_nMinusTwo = recursiveCase->Call(inlineFib, 1, nMinusTwo); } else fib_nMinusTwo = recursiveCase->Call("fib", 1, nMinusTwo); recursiveCase->Store("result", recursiveCase-> Add(fib_nMinusOne, fib_nMinusTwo)); #if defined(RFIB_DEBUG_OUTPUT) Call("printString", 1, ConstInt64((int64_t)prefix)); Call("printInt32", 1, Load("n")); Call("printString", 1, ConstInt64((int64_t)middle)); Call("printInt32", 1, Load("result")); Call("printString", 1, ConstInt64((int64_t)suffix)); #endif Return( Load("result")); return true; }