std::pair<BasicBlock*, Value*> powDoubleInt32(Procedure& procedure, BasicBlock* start, Origin origin, Value* x, Value* y) { BasicBlock* functionCallCase = procedure.addBlock(); BasicBlock* loopPreHeaderCase = procedure.addBlock(); BasicBlock* loopTestForEvenCase = procedure.addBlock(); BasicBlock* loopOdd = procedure.addBlock(); BasicBlock* loopEvenOdd = procedure.addBlock(); BasicBlock* continuation = procedure.addBlock(); Value* shouldGoSlowPath = start->appendNew<Value>(procedure, Above, origin, y, start->appendNew<Const32Value>(procedure, origin, maxExponentForIntegerMathPow)); start->appendNew<ControlValue>( procedure, Branch, origin, shouldGoSlowPath, FrequentedBlock(functionCallCase), FrequentedBlock(loopPreHeaderCase)); // Function call. Value* yAsDouble = functionCallCase->appendNew<Value>(procedure, IToD, origin, y); double (*powDouble)(double, double) = pow; Value* powResult = functionCallCase->appendNew<CCallValue>( procedure, Double, origin, functionCallCase->appendNew<ConstPtrValue>(procedure, origin, bitwise_cast<void*>(powDouble)), x, yAsDouble); UpsilonValue* powResultUpsilon = functionCallCase->appendNew<UpsilonValue>(procedure, origin, powResult); functionCallCase->appendNew<ControlValue>(procedure, Jump, origin, FrequentedBlock(continuation)); // Loop pre-header. Value* initialResult = loopPreHeaderCase->appendNew<ConstDoubleValue>(procedure, origin, 1.); UpsilonValue* initialLoopValue = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, initialResult); UpsilonValue* initialResultValue = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, initialResult); UpsilonValue* initialSquaredInput = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, x); UpsilonValue* initialLoopCounter = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, y); loopPreHeaderCase->appendNew<ControlValue>(procedure, Jump, origin, FrequentedBlock(loopTestForEvenCase)); // Test if what is left of the counter is even. Value* inLoopCounter = loopTestForEvenCase->appendNew<Value>(procedure, Phi, Int32, origin); Value* inLoopSquaredInput = loopTestForEvenCase->appendNew<Value>(procedure, Phi, Double, origin); Value* lastCounterBit = loopTestForEvenCase->appendNew<Value>(procedure, BitAnd, origin, inLoopCounter, loopTestForEvenCase->appendNew<Const32Value>(procedure, origin, 1)); loopTestForEvenCase->appendNew<ControlValue>( procedure, Branch, origin, lastCounterBit, FrequentedBlock(loopOdd), FrequentedBlock(loopEvenOdd)); // Counter is odd. Value* inLoopResult = loopOdd->appendNew<Value>(procedure, Phi, Double, origin); Value* updatedResult = loopOdd->appendNew<Value>(procedure, Mul, origin, inLoopResult, inLoopSquaredInput); UpsilonValue* updatedLoopResultUpsilon = loopOdd->appendNew<UpsilonValue>(procedure, origin, updatedResult); initialLoopValue->setPhi(inLoopResult); updatedLoopResultUpsilon->setPhi(inLoopResult); UpsilonValue* updatedLoopResult = loopOdd->appendNew<UpsilonValue>(procedure, origin, updatedResult); loopOdd->appendNew<ControlValue>(procedure, Jump, origin, FrequentedBlock(loopEvenOdd)); // Even value and following the Odd. Value* squaredInput = loopEvenOdd->appendNew<Value>(procedure, Mul, origin, inLoopSquaredInput, inLoopSquaredInput); UpsilonValue* squaredInputUpsilon = loopEvenOdd->appendNew<UpsilonValue>(procedure, origin, squaredInput); initialSquaredInput->setPhi(inLoopSquaredInput); squaredInputUpsilon->setPhi(inLoopSquaredInput); Value* updatedCounter = loopEvenOdd->appendNew<Value>(procedure, ZShr, origin, inLoopCounter, loopEvenOdd->appendNew<Const32Value>(procedure, origin, 1)); UpsilonValue* updatedCounterUpsilon = loopEvenOdd->appendNew<UpsilonValue>(procedure, origin, updatedCounter); initialLoopCounter->setPhi(inLoopCounter); updatedCounterUpsilon->setPhi(inLoopCounter); loopEvenOdd->appendNew<ControlValue>( procedure, Branch, origin, updatedCounter, FrequentedBlock(loopTestForEvenCase), FrequentedBlock(continuation)); // Inline loop. Value* finalResultPhi = continuation->appendNew<Value>(procedure, Phi, Double, origin); powResultUpsilon->setPhi(finalResultPhi); initialResultValue->setPhi(finalResultPhi); updatedLoopResult->setPhi(finalResultPhi); return std::make_pair(continuation, finalResultPhi); }