mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-19 19:29:31 +00:00
Implement LICM of calls in simple cases. This is sufficient to move around
sin/cos/strlen calls and stuff. This implements: LICM/call_sink_pure_function.ll LICM/call_sink_const_function.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12415 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
65a88e83e3
commit
118dd0ce3d
@ -57,6 +57,7 @@ namespace {
|
||||
Statistic<> NumSunk("licm", "Number of instructions sunk out of loop");
|
||||
Statistic<> NumHoisted("licm", "Number of instructions hoisted out of loop");
|
||||
Statistic<> NumMovedLoads("licm", "Number of load insts hoisted or sunk");
|
||||
Statistic<> NumMovedCalls("licm", "Number of call insts hoisted or sunk");
|
||||
Statistic<> NumPromoted("licm",
|
||||
"Number of memory locations promoted to registers");
|
||||
|
||||
@ -360,9 +361,35 @@ bool LICM::canSinkOrHoistInst(Instruction &I) {
|
||||
|
||||
// Don't hoist loads which have may-aliased stores in loop.
|
||||
return !pointerInvalidatedByLoop(LI->getOperand(0));
|
||||
} else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
// Handle obvious cases efficiently.
|
||||
if (Function *Callee = CI->getCalledFunction()) {
|
||||
if (AA->doesNotAccessMemory(Callee))
|
||||
return true;
|
||||
else if (AA->onlyReadsMemory(Callee)) {
|
||||
// If this call only reads from memory and there are no writes to memory
|
||||
// in the loop, we can hoist or sink the call as appropriate.
|
||||
bool FoundMod = false;
|
||||
for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
|
||||
I != E; ++I) {
|
||||
AliasSet &AS = *I;
|
||||
if (!AS.isForwardingAliasSet() && AS.isMod()) {
|
||||
FoundMod = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!FoundMod) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This should use mod/ref information to see if we can hoist or sink
|
||||
// the call.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CastInst>(I) ||
|
||||
isa<SelectInst>(I) ||
|
||||
isa<GetElementPtrInst>(I) || isa<VANextInst>(I) || isa<VAArgInst>(I);
|
||||
}
|
||||
|
||||
@ -412,6 +439,7 @@ void LICM::sink(Instruction &I) {
|
||||
const std::vector<BasicBlock*> &ExitBlocks = CurLoop->getExitBlocks();
|
||||
|
||||
if (isa<LoadInst>(I)) ++NumMovedLoads;
|
||||
else if (isa<CallInst>(I)) ++NumMovedCalls;
|
||||
++NumSunk;
|
||||
Changed = true;
|
||||
|
||||
@ -541,6 +569,7 @@ void LICM::hoist(Instruction &I) {
|
||||
Preheader->getInstList().insert(Preheader->getTerminator(), &I);
|
||||
|
||||
if (isa<LoadInst>(I)) ++NumMovedLoads;
|
||||
else if (isa<CallInst>(I)) ++NumMovedCalls;
|
||||
++NumHoisted;
|
||||
Changed = true;
|
||||
}
|
||||
@ -679,7 +708,8 @@ void LICM::findPromotableValuesInLoop(
|
||||
I != E; ++I) {
|
||||
AliasSet &AS = *I;
|
||||
// We can promote this alias set if it has a store, if it is a "Must" alias
|
||||
// set, if the pointer is loop invariant, if if we are not eliminating any volatile loads or stores.
|
||||
// set, if the pointer is loop invariant, if if we are not eliminating any
|
||||
// volatile loads or stores.
|
||||
if (!AS.isForwardingAliasSet() && AS.isMod() && AS.isMustAlias() &&
|
||||
!AS.isVolatile() && isLoopInvariant(AS.begin()->first)) {
|
||||
assert(AS.begin() != AS.end() &&
|
||||
|
Loading…
Reference in New Issue
Block a user