mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-16 11:24:39 +00:00
Use a switch rather than a sequence of "isa" tests.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61872 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -210,7 +210,8 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
|
|||||||
// be tracked because if it is captured then so is the original pointer.
|
// be tracked because if it is captured then so is the original pointer.
|
||||||
unsigned Depth = UD.getInt();
|
unsigned Depth = UD.getInt();
|
||||||
|
|
||||||
if (isa<StoreInst>(I)) {
|
switch (I->getOpcode()) {
|
||||||
|
case Instruction::Store:
|
||||||
if (V == I->getOperand(0)) {
|
if (V == I->getOperand(0)) {
|
||||||
// Stored the pointer - it may be captured. If it is stored to a local
|
// Stored the pointer - it may be captured. If it is stored to a local
|
||||||
// object (alloca) then track that object. Otherwise give up.
|
// object (alloca) then track that object. Otherwise give up.
|
||||||
@@ -230,14 +231,17 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Storing to the pointee does not cause the pointer to be captured.
|
// Storing to the pointee does not cause the pointer to be captured.
|
||||||
} else if (isa<FreeInst>(I)) {
|
break;
|
||||||
|
case Instruction::Free:
|
||||||
// Freeing a pointer does not cause it to be captured.
|
// Freeing a pointer does not cause it to be captured.
|
||||||
} else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
|
break;
|
||||||
|
case Instruction::Call:
|
||||||
|
case Instruction::Invoke: {
|
||||||
CallSite CS = CallSite::get(I);
|
CallSite CS = CallSite::get(I);
|
||||||
// Not captured if the callee is readonly and doesn't return a copy
|
// Not captured if the callee is readonly and doesn't return a copy
|
||||||
// through its return value.
|
// through its return value.
|
||||||
if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy)
|
if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
// Not captured if only passed via 'nocapture' arguments. Note that
|
// Not captured if only passed via 'nocapture' arguments. Note that
|
||||||
// calling a function pointer does not in itself cause the pointer to
|
// calling a function pointer does not in itself cause the pointer to
|
||||||
@@ -253,22 +257,33 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
|
|||||||
return true;
|
return true;
|
||||||
// Only passed via 'nocapture' arguments, or is the called function - not
|
// Only passed via 'nocapture' arguments, or is the called function - not
|
||||||
// captured.
|
// captured.
|
||||||
} else if (isa<BitCastInst>(I) || isa<LoadInst>(I) || isa<PHINode>(I) ||
|
break;
|
||||||
// Play safe and exclude GEP indices.
|
}
|
||||||
(isa<GetElementPtrInst>(I) && V == I->getOperand(0)) ||
|
case Instruction::BitCast:
|
||||||
// Play safe and exclude the select condition.
|
case Instruction::GetElementPtr:
|
||||||
(isa<SelectInst>(I) && V != I->getOperand(0))) {
|
case Instruction::Load:
|
||||||
|
case Instruction::PHI:
|
||||||
// Usually loads can be ignored because they dereference the original
|
case Instruction::Select:
|
||||||
// pointer. However the loaded value needs to be tracked if loading
|
// Track any uses of this instruction to see if they are captured.
|
||||||
// from an object that the original pointer was stored to.
|
// First handle any special cases.
|
||||||
if (isa<LoadInst>(I)) {
|
if (isa<GetElementPtrInst>(I)) {
|
||||||
|
// Play safe and do not accept being used as an index.
|
||||||
|
if (V != I->getOperand(0))
|
||||||
|
return true;
|
||||||
|
} else if (isa<SelectInst>(I)) {
|
||||||
|
// Play safe and do not accept being used as the condition.
|
||||||
|
if (V == I->getOperand(0))
|
||||||
|
return true;
|
||||||
|
} else if (isa<LoadInst>(I)) {
|
||||||
|
// Usually loads can be ignored because they dereference the original
|
||||||
|
// pointer. However the loaded value needs to be tracked if loading
|
||||||
|
// from an object that the original pointer was stored to.
|
||||||
if (Depth == 0)
|
if (Depth == 0)
|
||||||
// Loading the original pointer or a variation of it. This does not
|
// Loading the original pointer or a variation of it. This does not
|
||||||
// cause the pointer to be captured. Note that the loaded value might
|
// cause the pointer to be captured. Note that the loaded value might
|
||||||
// be the pointer itself (think of self-referential objects), but that
|
// be the pointer itself (think of self-referential objects), but that
|
||||||
// is fine as long as it's not this function that stored it there.
|
// is fine as long as it's not this function that stored it there.
|
||||||
continue;
|
break;
|
||||||
// Loading a pointer to (a pointer to...) the original pointer or a
|
// Loading a pointer to (a pointer to...) the original pointer or a
|
||||||
// variation of it. Track uses of the loaded value, noting that one
|
// variation of it. Track uses of the loaded value, noting that one
|
||||||
// dereference was performed. Note that the loaded value need not be
|
// dereference was performed. Note that the loaded value need not be
|
||||||
@@ -284,7 +299,8 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
|
|||||||
if (Visited.insert(UD))
|
if (Visited.insert(UD))
|
||||||
Worklist.push_back(UD);
|
Worklist.push_back(UD);
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
// Something else - be conservative and say it is captured.
|
// Something else - be conservative and say it is captured.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user