X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FExecutionEngine%2FInterpreter%2FExecution.cpp;h=26ef06bc982a01bd87935c8744b00d32eee6f896;hb=77113b627237fe2850676cccd809de1e05f03952;hp=9d5166dab81bbdda524a5dc0dba7413763d51f1b;hpb=fd506f551d2ca89cb757c75faf87809d9d07548d;p=oota-llvm.git diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 9d5166dab81..26ef06bc982 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -6,12 +6,8 @@ #include "Interpreter.h" #include "ExecutionAnnotations.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Function.h" -#include "llvm/iPHINode.h" -#include "llvm/iOther.h" -#include "llvm/iTerminators.h" -#include "llvm/iMemory.h" +#include "llvm/Module.h" +#include "llvm/Instructions.h" #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" #include "llvm/Assembly/Writer.h" @@ -161,8 +157,8 @@ static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) { void Interpreter::initializeExecutionEngine() { TheEE = this; - AnnotationManager::registerAnnotationFactory(MethodInfoAID, - &MethodInfo::Create); + AnnotationManager::registerAnnotationFactory(FunctionInfoAID, + &FunctionInfo::Create); initializeSignalHandlers(); } @@ -592,7 +588,7 @@ void Interpreter::executeRetInst(ReturnInst &I, ExecutionContext &SF) { } // Save previously executing meth - const Function *M = ECStack.back().CurMethod; + const Function *M = ECStack.back().CurFunction; // Pop the current stack frame... this invalidates SF ECStack.pop_back(); @@ -636,38 +632,69 @@ void Interpreter::executeRetInst(ReturnInst &I, ExecutionContext &SF) { } void Interpreter::executeBrInst(BranchInst &I, ExecutionContext &SF) { - SF.PrevBB = SF.CurBB; // Update PrevBB so that PHI nodes work... BasicBlock *Dest; Dest = I.getSuccessor(0); // Uncond branches have a fixed dest... if (!I.isUnconditional()) { Value *Cond = I.getCondition(); - GenericValue CondVal = getOperandValue(Cond, SF); - if (CondVal.BoolVal == 0) // If false cond... + if (getOperandValue(Cond, SF).BoolVal == 0) // If false cond... Dest = I.getSuccessor(1); } - SF.CurBB = Dest; // Update CurBB to branch destination - SF.CurInst = SF.CurBB->begin(); // Update new instruction ptr... + SwitchToNewBasicBlock(Dest, SF); } -static void executeSwitch(SwitchInst &I, ExecutionContext &SF) { +void Interpreter::executeSwitchInst(SwitchInst &I, ExecutionContext &SF) { GenericValue CondVal = getOperandValue(I.getOperand(0), SF); const Type *ElTy = I.getOperand(0)->getType(); - SF.PrevBB = SF.CurBB; // Update PrevBB so that PHI nodes work... - BasicBlock *Dest = 0; // Check to see if any of the cases match... - for (unsigned i = 2, e = I.getNumOperands(); i != e; i += 2) { + BasicBlock *Dest = 0; + for (unsigned i = 2, e = I.getNumOperands(); i != e; i += 2) if (executeSetEQInst(CondVal, getOperandValue(I.getOperand(i), SF), ElTy).BoolVal) { Dest = cast(I.getOperand(i+1)); break; } - } if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default - SF.CurBB = Dest; // Update CurBB to branch destination - SF.CurInst = SF.CurBB->begin(); // Update new instruction ptr... + SwitchToNewBasicBlock(Dest, SF); +} + +// SwitchToNewBasicBlock - This method is used to jump to a new basic block. +// This function handles the actual updating of block and instruction iterators +// as well as execution of all of the PHI nodes in the destination block. +// +// This method does this because all of the PHI nodes must be executed +// atomically, reading their inputs before any of the results are updated. Not +// doing this can cause problems if the PHI nodes depend on other PHI nodes for +// their inputs. If the input PHI node is updated before it is read, incorrect +// results can happen. Thus we use a two phase approach. +// +void Interpreter::SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF){ + BasicBlock *PrevBB = SF.CurBB; // Remember where we came from... + SF.CurBB = Dest; // Update CurBB to branch destination + SF.CurInst = SF.CurBB->begin(); // Update new instruction ptr... + + if (!isa(SF.CurInst)) return; // Nothing fancy to do + + // Loop over all of the PHI nodes in the current block, reading their inputs. + std::vector ResultValues; + + for (; PHINode *PN = dyn_cast(SF.CurInst); ++SF.CurInst) { + // Search for the value corresponding to this previous bb... + int i = PN->getBasicBlockIndex(PrevBB); + assert(i != -1 && "PHINode doesn't contain entry for predecessor??"); + Value *IncomingValue = PN->getIncomingValue(i); + + // Save the incoming value for this PHI node... + ResultValues.push_back(getOperandValue(IncomingValue, SF)); + } + + // Now loop over all of the PHI nodes setting their values... + SF.CurInst = SF.CurBB->begin(); + for (unsigned i = 0; PHINode *PN = dyn_cast(SF.CurInst); + ++SF.CurInst, ++i) + SetValue(PN, ResultValues[i], SF); } @@ -765,74 +792,7 @@ static void executeGEPInst(GetElementPtrInst &I, ExecutionContext &SF) { void Interpreter::executeLoadInst(LoadInst &I, ExecutionContext &SF) { GenericValue SRC = getOperandValue(I.getPointerOperand(), SF); GenericValue *Ptr = (GenericValue*)GVTOP(SRC); - GenericValue Result; - - if (TD.isLittleEndian()) { - switch (I.getType()->getPrimitiveID()) { - case Type::BoolTyID: - case Type::UByteTyID: - case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; - case Type::UShortTyID: - case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[0] | - ((unsigned)Ptr->Untyped[1] << 8); - break; - case Type::FloatTyID: - case Type::UIntTyID: - case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[0] | - ((unsigned)Ptr->Untyped[1] << 8) | - ((unsigned)Ptr->Untyped[2] << 16) | - ((unsigned)Ptr->Untyped[3] << 24); - break; - case Type::DoubleTyID: - case Type::ULongTyID: - case Type::LongTyID: - case Type::PointerTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[0] | - ((uint64_t)Ptr->Untyped[1] << 8) | - ((uint64_t)Ptr->Untyped[2] << 16) | - ((uint64_t)Ptr->Untyped[3] << 24) | - ((uint64_t)Ptr->Untyped[4] << 32) | - ((uint64_t)Ptr->Untyped[5] << 40) | - ((uint64_t)Ptr->Untyped[6] << 48) | - ((uint64_t)Ptr->Untyped[7] << 56); - break; - default: - std::cout << "Cannot load value of type " << *I.getType() << "!\n"; - abort(); - } - } else { - switch (I.getType()->getPrimitiveID()) { - case Type::BoolTyID: - case Type::UByteTyID: - case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; - case Type::UShortTyID: - case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[1] | - ((unsigned)Ptr->Untyped[0] << 8); - break; - case Type::FloatTyID: - case Type::UIntTyID: - case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[3] | - ((unsigned)Ptr->Untyped[2] << 8) | - ((unsigned)Ptr->Untyped[1] << 16) | - ((unsigned)Ptr->Untyped[0] << 24); - break; - case Type::DoubleTyID: - case Type::ULongTyID: - case Type::LongTyID: - case Type::PointerTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[7] | - ((uint64_t)Ptr->Untyped[6] << 8) | - ((uint64_t)Ptr->Untyped[5] << 16) | - ((uint64_t)Ptr->Untyped[4] << 24) | - ((uint64_t)Ptr->Untyped[3] << 32) | - ((uint64_t)Ptr->Untyped[2] << 40) | - ((uint64_t)Ptr->Untyped[1] << 48) | - ((uint64_t)Ptr->Untyped[0] << 56); - break; - default: - std::cout << "Cannot load value of type " << *I.getType() << "!\n"; - abort(); - } - } - + GenericValue Result = LoadValueFromMemory(Ptr, I.getType()); SetValue(&I, Result, SF); } @@ -880,24 +840,7 @@ void Interpreter::executeCallInst(CallInst &I, ExecutionContext &SF) { // and treat it as a function pointer. GenericValue SRC = getOperandValue(I.getCalledValue(), SF); - callMethod((Function*)GVTOP(SRC), ArgVals); -} - -static void executePHINode(PHINode &I, ExecutionContext &SF) { - BasicBlock *PrevBB = SF.PrevBB; - Value *IncomingValue = 0; - - // Search for the value corresponding to this previous bb... - for (unsigned i = I.getNumIncomingValues(); i > 0;) { - if (I.getIncomingBlock(--i) == PrevBB) { - IncomingValue = I.getIncomingValue(i); - break; - } - } - assert(IncomingValue && "No PHI node predecessor for current PrevBB!"); - - // Found the value, set as the result... - SetValue(&I, getOperandValue(IncomingValue, SF), SF); + callFunction((Function*)GVTOP(SRC), ArgVals); } #define IMPLEMENT_SHIFT(OP, TY) \ @@ -1009,12 +952,32 @@ static void executeCastInst(CastInst &I, ExecutionContext &SF) { SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF); } +static void executeVarArgInst(VarArgInst &I, ExecutionContext &SF) { + // Get the pointer to the valist element. LLI treats the valist in memory as + // an integer. + GenericValue VAListPtr = getOperandValue(I.getOperand(0), SF); + + // Load the pointer + GenericValue VAList = + TheEE->LoadValueFromMemory((GenericValue *)GVTOP(VAListPtr), Type::UIntTy); + + unsigned Argument = VAList.IntVal++; + + // Update the valist to point to the next argument... + TheEE->StoreValueToMemory(VAList, (GenericValue *)GVTOP(VAListPtr), + Type::UIntTy); + + // Set the value... + assert(Argument < SF.VarArgs.size() && + "Accessing past the last vararg argument!"); + SetValue(&I, SF.VarArgs[Argument], SF); +} //===----------------------------------------------------------------------===// // Dispatch and Execution Code //===----------------------------------------------------------------------===// -MethodInfo::MethodInfo(Function *F) : Annotation(MethodInfoAID) { +FunctionInfo::FunctionInfo(Function *F) : Annotation(FunctionInfoAID) { // Assign slot numbers to the function arguments... for (Function::const_aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI) AI->addAnnotation(new SlotNumber(getValueSlot(AI))); @@ -1027,7 +990,7 @@ MethodInfo::MethodInfo(Function *F) : Annotation(MethodInfoAID) { II->addAnnotation(new InstNumber(++InstNum, getValueSlot(II))); } -unsigned MethodInfo::getValueSlot(const Value *V) { +unsigned FunctionInfo::getValueSlot(const Value *V) { unsigned Plane = V->getType()->getUniqueID(); if (Plane >= NumPlaneElements.size()) NumPlaneElements.resize(Plane+1, 0); @@ -1036,16 +999,16 @@ unsigned MethodInfo::getValueSlot(const Value *V) { //===----------------------------------------------------------------------===// -// callMethod - Execute the specified function... +// callFunction - Execute the specified function... // -void Interpreter::callMethod(Function *M, - const std::vector &ArgVals) { +void Interpreter::callFunction(Function *F, + const std::vector &ArgVals) { assert((ECStack.empty() || ECStack.back().Caller == 0 || ECStack.back().Caller->getNumOperands()-1 == ArgVals.size()) && "Incorrect number of arguments passed into function call!"); - if (M->isExternal()) { - GenericValue Result = callExternalMethod(M, ArgVals); - const Type *RetTy = M->getReturnType(); + if (F->isExternal()) { + GenericValue Result = callExternalFunction(F, ArgVals); + const Type *RetTy = F->getReturnType(); // Copy the result back into the result variable if we are not returning // void. @@ -1057,7 +1020,7 @@ void Interpreter::callMethod(Function *M, SF.Caller = 0; // We returned from the call... } else if (!QuietMode) { // print it. - CW << "Function " << M->getType() << " \"" << M->getName() + CW << "Function " << F->getType() << " \"" << F->getName() << "\" returned "; print(RetTy, Result); std::cout << "\n"; @@ -1074,34 +1037,39 @@ void Interpreter::callMethod(Function *M, // the function. Also calculate the number of values for each type slot // active. // - MethodInfo *MethInfo = (MethodInfo*)M->getOrCreateAnnotation(MethodInfoAID); + FunctionInfo *FuncInfo = + (FunctionInfo*)F->getOrCreateAnnotation(FunctionInfoAID); ECStack.push_back(ExecutionContext()); // Make a new stack frame... ExecutionContext &StackFrame = ECStack.back(); // Fill it in... - StackFrame.CurMethod = M; - StackFrame.CurBB = M->begin(); + StackFrame.CurFunction = F; + StackFrame.CurBB = F->begin(); StackFrame.CurInst = StackFrame.CurBB->begin(); - StackFrame.MethInfo = MethInfo; + StackFrame.FuncInfo = FuncInfo; // Initialize the values to nothing... - StackFrame.Values.resize(MethInfo->NumPlaneElements.size()); - for (unsigned i = 0; i < MethInfo->NumPlaneElements.size(); ++i) { - StackFrame.Values[i].resize(MethInfo->NumPlaneElements[i]); + StackFrame.Values.resize(FuncInfo->NumPlaneElements.size()); + for (unsigned i = 0; i < FuncInfo->NumPlaneElements.size(); ++i) { + StackFrame.Values[i].resize(FuncInfo->NumPlaneElements[i]); // Taint the initial values of stuff memset(&StackFrame.Values[i][0], 42, - MethInfo->NumPlaneElements[i]*sizeof(GenericValue)); + FuncInfo->NumPlaneElements[i]*sizeof(GenericValue)); } - StackFrame.PrevBB = 0; // No previous BB for PHI nodes... - // Run through the function arguments and initialize their values... - assert(ArgVals.size() == M->asize() && + assert((ArgVals.size() == F->asize() || + (ArgVals.size() > F->asize() && F->getFunctionType()->isVarArg())) && "Invalid number of values passed to function invocation!"); + + // Handle non-varargs arguments... unsigned i = 0; - for (Function::aiterator AI = M->abegin(), E = M->aend(); AI != E; ++AI, ++i) + for (Function::aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI, ++i) SetValue(AI, ArgVals[i], StackFrame); + + // Handle varargs arguments... + StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end()); } // executeInstruction - Interpret a single instruction, increment the "PC", and @@ -1146,7 +1114,9 @@ bool Interpreter::executeInstruction() { // Terminators case Instruction::Ret: executeRetInst (cast(I), SF); break; case Instruction::Br: executeBrInst (cast(I), SF); break; - case Instruction::Switch: executeSwitch (cast(I), SF); break; + case Instruction::Switch: executeSwitchInst(cast(I), SF);break; + // Invoke not handled! + // Memory Instructions case Instruction::Alloca: case Instruction::Malloc: executeAllocInst((AllocationInst&)I, SF); break; @@ -1158,10 +1128,11 @@ bool Interpreter::executeInstruction() { // Miscellaneous Instructions case Instruction::Call: executeCallInst (cast (I), SF); break; - case Instruction::PHINode: executePHINode (cast (I), SF); break; + case Instruction::PHINode: assert(0 && "PHI nodes already handled!"); + case Instruction::Cast: executeCastInst (cast (I), SF); break; case Instruction::Shl: executeShlInst (cast(I), SF); break; case Instruction::Shr: executeShrInst (cast(I), SF); break; - case Instruction::Cast: executeCastInst (cast (I), SF); break; + case Instruction::VarArg: executeVarArgInst(cast(I),SF); break; default: std::cout << "Don't know how to execute this instruction!\n-->" << I; abort(); @@ -1339,7 +1310,7 @@ void Interpreter::infoValue(const std::string &Name) { // void Interpreter::printStackFrame(int FrameNo) { if (FrameNo == -1) FrameNo = CurFrame; - Function *F = ECStack[FrameNo].CurMethod; + Function *F = ECStack[FrameNo].CurFunction; const Type *RetTy = F->getReturnType(); CW << ((FrameNo == CurFrame) ? '>' : '-') << "#" << FrameNo << ". "