[llvm-commits] CVS: llvm/tools/lli/Interpreter/Execution.cpp Interpreter.h
Chris Lattner
lattner at cs.uiuc.edu
Sat May 10 15:22:01 PDT 2003
Changes in directory llvm/tools/lli/Interpreter:
Execution.cpp updated: 1.87 -> 1.88
Interpreter.h updated: 1.27 -> 1.28
---
Log message:
Fix testcase: SingleSource/UnitTests/2003-05-02-DependantPHI.c
---
Diffs of the changes:
Index: llvm/tools/lli/Interpreter/Execution.cpp
diff -u llvm/tools/lli/Interpreter/Execution.cpp:1.87 llvm/tools/lli/Interpreter/Execution.cpp:1.88
--- llvm/tools/lli/Interpreter/Execution.cpp:1.87 Thu May 8 11:52:43 2003
+++ llvm/tools/lli/Interpreter/Execution.cpp Sat May 10 15:21:16 2003
@@ -632,38 +632,69 @@
}
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);
}
@@ -812,23 +843,6 @@
callFunction((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);
-}
-
#define IMPLEMENT_SHIFT(OP, TY) \
case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.UByteVal; break
@@ -1043,8 +1057,6 @@
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() == F->asize() ||
@@ -1102,7 +1114,9 @@
// 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;
@@ -1114,7 +1128,7 @@
// 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;
Index: llvm/tools/lli/Interpreter/Interpreter.h
diff -u llvm/tools/lli/Interpreter/Interpreter.h:1.27 llvm/tools/lli/Interpreter/Interpreter.h:1.28
--- llvm/tools/lli/Interpreter/Interpreter.h:1.27 Thu May 8 11:18:31 2003
+++ llvm/tools/lli/Interpreter/Interpreter.h Sat May 10 15:21:16 2003
@@ -23,6 +23,7 @@
class CallInst;
class ReturnInst;
class BranchInst;
+class SwitchInst;
class LoadInst;
class StoreInst;
class AllocationInst;
@@ -70,7 +71,6 @@
std::vector<ValuePlaneTy> Values;// ValuePlanes for each type
std::vector<GenericValue> VarArgs; // Values passed through an ellipsis
- BasicBlock *PrevBB; // The previous BB or null if in first BB
CallInst *Caller; // Holds the call that called subframes.
// NULL if main func or debugger invoked fn
AllocaHolderHandle Allocas; // Track memory allocated by alloca
@@ -137,6 +137,7 @@
void executeCallInst(CallInst &I, ExecutionContext &SF);
void executeRetInst(ReturnInst &I, ExecutionContext &SF);
void executeBrInst(BranchInst &I, ExecutionContext &SF);
+ void executeSwitchInst(SwitchInst &I, ExecutionContext &SF);
void executeAllocInst(AllocationInst &I, ExecutionContext &SF);
GenericValue callExternalFunction(Function *F,
const std::vector<GenericValue> &ArgVals);
@@ -161,6 +162,12 @@
private: // Helper functions
+ // SwitchToNewBasicBlock - Start execution in a new basic block and run any
+ // PHI nodes in the top of the block. This is used for intraprocedural
+ // control flow.
+ //
+ void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF);
+
void *getPointerToFunction(const Function *F) { return (void*)F; }
// getCurrentExecutablePath() - Return the directory that the lli executable
More information about the llvm-commits
mailing list