mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-05 12:31:33 +00:00
Split part of EvaluateFunction into a new EvaluateBlock method. No functionality
change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149861 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
aae875c27c
commit
da82fd411e
@ -2282,9 +2282,6 @@ static Constant *ComputeLoadResult(Constant *P,
|
||||
return 0; // don't know how to evaluate.
|
||||
}
|
||||
|
||||
/// EvaluateFunction - Evaluate a call to function F, returning true if
|
||||
/// successful, false if we can't evaluate it. ActualArgs contains the formal
|
||||
/// arguments for the function.
|
||||
static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
const SmallVectorImpl<Constant*> &ActualArgs,
|
||||
std::vector<Function*> &CallStack,
|
||||
@ -2292,30 +2289,21 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
std::vector<GlobalVariable*> &AllocaTmps,
|
||||
SmallPtrSet<Constant*, 8> &SimpleConstants,
|
||||
const TargetData *TD,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
// Check to see if this function is already executing (recursion). If so,
|
||||
// bail out. TODO: we might want to accept limited recursion.
|
||||
if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end())
|
||||
return false;
|
||||
|
||||
CallStack.push_back(F);
|
||||
|
||||
/// Values - As we compute SSA register values, we store their contents here.
|
||||
DenseMap<Value*, Constant*> Values;
|
||||
|
||||
// Initialize arguments to the incoming values specified.
|
||||
unsigned ArgNo = 0;
|
||||
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E;
|
||||
++AI, ++ArgNo)
|
||||
Values[AI] = ActualArgs[ArgNo];
|
||||
|
||||
/// 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
|
||||
/// track of what we have executed so we can detect recursive cases etc.
|
||||
SmallPtrSet<BasicBlock*, 32> ExecutedBlocks;
|
||||
const TargetLibraryInfo *TLI);
|
||||
|
||||
/// EvaluateBlock - Evaluate all instructions in block BB, returning true if
|
||||
/// successful, false if we can't evaluate it. NewBB returns the next BB that
|
||||
/// control flows into, or null upon return.
|
||||
static bool EvaluateBlock(BasicBlock *BB, BasicBlock *&NextBB,
|
||||
std::vector<Function*> &CallStack,
|
||||
DenseMap<Value*, Constant*> &Values,
|
||||
DenseMap<Constant*, Constant*> &MutatedMemory,
|
||||
std::vector<GlobalVariable*> &AllocaTmps,
|
||||
SmallPtrSet<Constant*, 8> &SimpleConstants,
|
||||
const TargetData *TD,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
// CurInst - The current instruction we're evaluating.
|
||||
BasicBlock::iterator CurInst = F->begin()->begin();
|
||||
BasicBlock::iterator CurInst = BB->getFirstNonPHI();
|
||||
|
||||
// This is the main evaluation loop.
|
||||
while (1) {
|
||||
@ -2342,7 +2330,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
// stored value.
|
||||
Ptr = CE->getOperand(0);
|
||||
|
||||
Type *NewTy=cast<PointerType>(Ptr->getType())->getElementType();
|
||||
Type *NewTy = cast<PointerType>(Ptr->getType())->getElementType();
|
||||
|
||||
// In order to push the bitcast onto the stored value, a bitcast
|
||||
// from NewTy to Val's type must be legal. If it's not, we can try
|
||||
@ -2354,7 +2342,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
if (StructType *STy = dyn_cast<StructType>(NewTy)) {
|
||||
NewTy = STy->getTypeAtIndex(0U);
|
||||
|
||||
IntegerType *IdxTy =IntegerType::get(NewTy->getContext(), 32);
|
||||
IntegerType *IdxTy = IntegerType::get(NewTy->getContext(), 32);
|
||||
Constant *IdxZero = ConstantInt::get(IdxTy, 0, false);
|
||||
Constant * const IdxList[] = {IdxZero, IdxZero};
|
||||
|
||||
@ -2363,7 +2351,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
// If we can't improve the situation by introspecting NewTy,
|
||||
// we have to give up.
|
||||
} else {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2467,57 +2455,37 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
InstResult = RetVal;
|
||||
}
|
||||
} else if (isa<TerminatorInst>(CurInst)) {
|
||||
BasicBlock *NewBB = 0;
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {
|
||||
if (BI->isUnconditional()) {
|
||||
NewBB = BI->getSuccessor(0);
|
||||
NextBB = BI->getSuccessor(0);
|
||||
} else {
|
||||
ConstantInt *Cond =
|
||||
dyn_cast<ConstantInt>(getVal(Values, BI->getCondition()));
|
||||
if (!Cond) return false; // Cannot determine.
|
||||
|
||||
NewBB = BI->getSuccessor(!Cond->getZExtValue());
|
||||
NextBB = BI->getSuccessor(!Cond->getZExtValue());
|
||||
}
|
||||
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurInst)) {
|
||||
ConstantInt *Val =
|
||||
dyn_cast<ConstantInt>(getVal(Values, SI->getCondition()));
|
||||
if (!Val) return false; // Cannot determine.
|
||||
unsigned ValTISucc = SI->resolveSuccessorIndex(SI->findCaseValue(Val));
|
||||
NewBB = SI->getSuccessor(ValTISucc);
|
||||
NextBB = SI->getSuccessor(ValTISucc);
|
||||
} else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(CurInst)) {
|
||||
Value *Val = getVal(Values, IBI->getAddress())->stripPointerCasts();
|
||||
if (BlockAddress *BA = dyn_cast<BlockAddress>(Val))
|
||||
NewBB = BA->getBasicBlock();
|
||||
NextBB = BA->getBasicBlock();
|
||||
else
|
||||
return false; // Cannot determine.
|
||||
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(CurInst)) {
|
||||
if (RI->getNumOperands())
|
||||
RetVal = getVal(Values, RI->getOperand(0));
|
||||
|
||||
CallStack.pop_back(); // return from fn.
|
||||
return true; // We succeeded at evaluating this ctor!
|
||||
} else if (isa<ReturnInst>(CurInst)) {
|
||||
NextBB = 0;
|
||||
} else {
|
||||
// invoke, unwind, resume, unreachable.
|
||||
return false; // Cannot handle this terminator.
|
||||
}
|
||||
|
||||
// Okay, we succeeded in evaluating this control flow. See if we have
|
||||
// executed the new block before. If so, we have a looping function,
|
||||
// which we cannot evaluate in reasonable time.
|
||||
if (!ExecutedBlocks.insert(NewBB))
|
||||
return false; // looped!
|
||||
|
||||
// Okay, we have never been in this block before. Check to see if there
|
||||
// are any PHI nodes. If so, evaluate them with information about where
|
||||
// we came from.
|
||||
BasicBlock *OldBB = CurInst->getParent();
|
||||
CurInst = NewBB->begin();
|
||||
PHINode *PN;
|
||||
for (; (PN = dyn_cast<PHINode>(CurInst)); ++CurInst)
|
||||
Values[PN] = getVal(Values, PN->getIncomingValueForBlock(OldBB));
|
||||
|
||||
// Do NOT increment CurInst. We know that the terminator had no value.
|
||||
continue;
|
||||
// We succeeded at evaluating this block!
|
||||
return true;
|
||||
} else {
|
||||
// Did not know how to evaluate this!
|
||||
return false;
|
||||
@ -2535,6 +2503,76 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
}
|
||||
}
|
||||
|
||||
/// EvaluateFunction - Evaluate a call to function F, returning true if
|
||||
/// successful, false if we can't evaluate it. ActualArgs contains the formal
|
||||
/// arguments for the function.
|
||||
static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
||||
const SmallVectorImpl<Constant*> &ActualArgs,
|
||||
std::vector<Function*> &CallStack,
|
||||
DenseMap<Constant*, Constant*> &MutatedMemory,
|
||||
std::vector<GlobalVariable*> &AllocaTmps,
|
||||
SmallPtrSet<Constant*, 8> &SimpleConstants,
|
||||
const TargetData *TD,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
// Check to see if this function is already executing (recursion). If so,
|
||||
// bail out. TODO: we might want to accept limited recursion.
|
||||
if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end())
|
||||
return false;
|
||||
|
||||
CallStack.push_back(F);
|
||||
|
||||
/// Values - As we compute SSA register values, we store their contents here.
|
||||
DenseMap<Value*, Constant*> Values;
|
||||
|
||||
// Initialize arguments to the incoming values specified.
|
||||
unsigned ArgNo = 0;
|
||||
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E;
|
||||
++AI, ++ArgNo)
|
||||
Values[AI] = ActualArgs[ArgNo];
|
||||
|
||||
// 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
|
||||
// track of what we have executed so we can detect recursive cases etc.
|
||||
SmallPtrSet<BasicBlock*, 32> ExecutedBlocks;
|
||||
|
||||
// CurBB - The current basic block we're evaluating.
|
||||
BasicBlock *CurBB = F->begin();
|
||||
|
||||
while (1) {
|
||||
BasicBlock *NextBB;
|
||||
if (!EvaluateBlock(CurBB, NextBB, CallStack, Values, MutatedMemory,
|
||||
AllocaTmps, SimpleConstants, TD, TLI))
|
||||
return false;
|
||||
|
||||
if (NextBB == 0) {
|
||||
// Successfully running until there's no next block means that we found
|
||||
// the return. Fill it the return value and pop the call stack.
|
||||
ReturnInst *RI = cast<ReturnInst>(CurBB->getTerminator());
|
||||
if (RI->getNumOperands())
|
||||
RetVal = getVal(Values, RI->getOperand(0));
|
||||
CallStack.pop_back();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Okay, we succeeded in evaluating this control flow. See if we have
|
||||
// executed the new block before. If so, we have a looping function,
|
||||
// which we cannot evaluate in reasonable time.
|
||||
if (!ExecutedBlocks.insert(NextBB))
|
||||
return false; // looped!
|
||||
|
||||
// Okay, we have never been in this block before. Check to see if there
|
||||
// are any PHI nodes. If so, evaluate them with information about where
|
||||
// we came from.
|
||||
PHINode *PN = 0;
|
||||
for (BasicBlock::iterator Inst = NextBB->begin();
|
||||
(PN = dyn_cast<PHINode>(Inst)); ++Inst)
|
||||
Values[PN] = getVal(Values, PN->getIncomingValueForBlock(CurBB));
|
||||
|
||||
// Advance to the next block.
|
||||
CurBB = NextBB;
|
||||
}
|
||||
}
|
||||
|
||||
/// EvaluateStaticConstructor - Evaluate static constructors in the function, if
|
||||
/// we can. Return true if we can, false otherwise.
|
||||
static bool EvaluateStaticConstructor(Function *F, const TargetData *TD,
|
||||
|
Loading…
Reference in New Issue
Block a user