Refactor this code a bit, no functionality changes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23460 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-09-27 04:27:01 +00:00
parent 5e8d2dc197
commit 8a7cc6e71c

View File

@ -1363,33 +1363,26 @@ static Constant *ComputeLoadResult(Constant *P,
return 0; // don't know how to evaluate. return 0; // don't know how to evaluate.
} }
/// EvaluateStaticConstructor - Evaluate static constructors in the function, if /// EvaluateFunction - Evaluate a call to function F, returning true if
/// we can. Return true if we can, false otherwise. /// successful, false if we can't evaluate it. ActualArgs contains the formal
static bool EvaluateStaticConstructor(Function *F) { /// arguments for the function.
static bool EvaluateFunction(Function *F,
const std::vector<Constant*> &ActualArgs,
std::vector<Function*> &CallStack,
std::map<Constant*, Constant*> &MutatedMemory,
std::vector<GlobalVariable*> &AllocaTmps) {
/// Values - As we compute SSA register values, we store their contents here. /// Values - As we compute SSA register values, we store their contents here.
std::map<Value*, Constant*> Values; std::map<Value*, Constant*> Values;
/// MutatedMemory - For each store we execute, we update this map. Loads
/// check this to get the most up-to-date value. If evaluation is successful,
/// this state is committed to the process.
std::map<Constant*, Constant*> MutatedMemory;
/// ExecutedBlocks - We only handle non-looping, non-recursive code. As such, /// ExecutedBlocks - We only handle non-looping, non-recursive code. As such,
/// we can only evaluate any one basic block at most once. This set keeps /// we can only evaluate any one basic block at most once. This set keeps
/// track of what we have executed so we can detect recursive cases etc. /// track of what we have executed so we can detect recursive cases etc.
std::set<BasicBlock*> ExecutedBlocks; std::set<BasicBlock*> ExecutedBlocks;
/// AllocaTmps - To 'execute' an alloca, we create a temporary global variable
/// to represent its body. This allows us to delete the temporary globals
/// when we are done.
std::vector<GlobalVariable*> AllocaTmps;
// CurInst - The current instruction we're evaluating. // CurInst - The current instruction we're evaluating.
BasicBlock::iterator CurInst = F->begin()->begin(); BasicBlock::iterator CurInst = F->begin()->begin();
ExecutedBlocks.insert(F->begin()); ExecutedBlocks.insert(F->begin());
bool EvaluationSuccessful = false;
// This is the main evaluation loop. // This is the main evaluation loop.
while (1) { while (1) {
Constant *InstResult = 0; Constant *InstResult = 0;
@ -1454,8 +1447,7 @@ static bool EvaluateStaticConstructor(Function *F) {
NewBB = SI->getSuccessor(SI->findCaseValue(Val)); NewBB = SI->getSuccessor(SI->findCaseValue(Val));
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(CurInst)) { } else if (ReturnInst *RI = dyn_cast<ReturnInst>(CurInst)) {
assert(RI->getNumOperands() == 0); assert(RI->getNumOperands() == 0);
EvaluationSuccessful = true; return true; // We succeeded at evaluating this ctor!
break; // We succeeded at evaluating this ctor!
} else { } else {
// unwind, unreachable. // unwind, unreachable.
break; // Cannot handle this terminator. break; // Cannot handle this terminator.
@ -1492,10 +1484,34 @@ static bool EvaluateStaticConstructor(Function *F) {
++CurInst; ++CurInst;
} }
if (EvaluationSuccessful) { return false;
}
/// EvaluateStaticConstructor - Evaluate static constructors in the function, if
/// we can. Return true if we can, false otherwise.
static bool EvaluateStaticConstructor(Function *F) {
/// MutatedMemory - For each store we execute, we update this map. Loads
/// check this to get the most up-to-date value. If evaluation is successful,
/// this state is committed to the process.
std::map<Constant*, Constant*> MutatedMemory;
/// AllocaTmps - To 'execute' an alloca, we create a temporary global variable
/// to represent its body. This vector is needed so we can delete the
/// temporary globals when we are done.
std::vector<GlobalVariable*> AllocaTmps;
/// CallStack - This is used to detect recursion. In pathological situations
/// we could hit exponential behavior, but at least there is nothing
/// unbounded.
std::vector<Function*> CallStack;
// Call the function.
bool EvalSuccess = EvaluateFunction(F, std::vector<Constant*>(), CallStack,
MutatedMemory, AllocaTmps);
if (EvalSuccess) {
// We succeeded at evaluation: commit the result. // We succeeded at evaluation: commit the result.
DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" << DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" <<
F->getName() << "'\n"); F->getName() << "' to " << MutatedMemory.size() << " stores.\n");
for (std::map<Constant*, Constant*>::iterator I = MutatedMemory.begin(), for (std::map<Constant*, Constant*>::iterator I = MutatedMemory.begin(),
E = MutatedMemory.end(); I != E; ++I) E = MutatedMemory.end(); I != E; ++I)
CommitValueTo(I->second, I->first); CommitValueTo(I->second, I->first);
@ -1506,7 +1522,7 @@ static bool EvaluateStaticConstructor(Function *F) {
while (!AllocaTmps.empty()) { while (!AllocaTmps.empty()) {
GlobalVariable *Tmp = AllocaTmps.back(); GlobalVariable *Tmp = AllocaTmps.back();
AllocaTmps.pop_back(); AllocaTmps.pop_back();
// If there are still users of the alloca, the program is doing something // If there are still users of the alloca, the program is doing something
// silly, e.g. storing the address of the alloca somewhere and using it // silly, e.g. storing the address of the alloca somewhere and using it
// later. Since this is undefined, we'll just make it be null. // later. Since this is undefined, we'll just make it be null.
@ -1515,10 +1531,12 @@ static bool EvaluateStaticConstructor(Function *F) {
delete Tmp; delete Tmp;
} }
return EvaluationSuccessful; return EvalSuccess;
} }
/// OptimizeGlobalCtorsList - Simplify and evaluation global ctors if possible. /// OptimizeGlobalCtorsList - Simplify and evaluation global ctors if possible.
/// Return true if anything changed. /// Return true if anything changed.
bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) { bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) {