Fix testcase: SingleSource/UnitTests/2003-05-02-DependantPHI.c
[oota-llvm.git] / lib / ExecutionEngine / Interpreter / Execution.cpp
index 9d5166dab81bbdda524a5dc0dba7413763d51f1b..26ef06bc982a01bd87935c8744b00d32eee6f896 100644 (file)
@@ -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<BasicBlock>(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<PHINode>(SF.CurInst)) return;  // Nothing fancy to do
+
+  // Loop over all of the PHI nodes in the current block, reading their inputs.
+  std::vector<GenericValue> ResultValues;
+
+  for (; PHINode *PN = dyn_cast<PHINode>(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<PHINode>(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<GenericValue> &ArgVals) {
+void Interpreter::callFunction(Function *F,
+                               const std::vector<GenericValue> &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<ReturnInst>(I), SF); break;
     case Instruction::Br:      executeBrInst   (cast<BranchInst>(I), SF); break;
-    case Instruction::Switch:  executeSwitch   (cast<SwitchInst>(I), SF); break;
+    case Instruction::Switch:  executeSwitchInst(cast<SwitchInst>(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<CallInst> (I), SF); break;
-    case Instruction::PHINode: executePHINode  (cast<PHINode>  (I), SF); break;
+    case Instruction::PHINode: assert(0 && "PHI nodes already handled!");
+    case Instruction::Cast:    executeCastInst (cast<CastInst> (I), SF); break;
     case Instruction::Shl:     executeShlInst  (cast<ShiftInst>(I), SF); break;
     case Instruction::Shr:     executeShrInst  (cast<ShiftInst>(I), SF); break;
-    case Instruction::Cast:    executeCastInst (cast<CastInst> (I), SF); break;
+    case Instruction::VarArg:  executeVarArgInst(cast<VarArgInst>(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 << ". "