mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
Do extremely simple sinking of instructions when they are only used in a
successor block. This turns cases like this: x = a op b if (c) { use x } into: if (c) { x = a op b use x } This triggers 3965 times in spec, and is tested by Regression/Transforms/InstCombine/sink_instruction.ll This appears to expose a bug in the X86 backend for 177.mesa, which I'm looking in to. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18677 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a95cf3024b
commit
ea1c45405d
@ -43,12 +43,13 @@
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||
#include "llvm/Support/InstIterator.h"
|
||||
#include "llvm/Support/InstVisitor.h"
|
||||
#include "llvm/Support/PatternMatch.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
using namespace llvm::PatternMatch;
|
||||
@ -57,6 +58,7 @@ namespace {
|
||||
Statistic<> NumCombined ("instcombine", "Number of insts combined");
|
||||
Statistic<> NumConstProp("instcombine", "Number of constant folds");
|
||||
Statistic<> NumDeadInst ("instcombine", "Number of dead inst eliminated");
|
||||
Statistic<> NumSunkInst ("instcombine", "Number of instructions sunk");
|
||||
|
||||
class InstCombiner : public FunctionPass,
|
||||
public InstVisitor<InstCombiner, Instruction*> {
|
||||
@ -4189,6 +4191,32 @@ void InstCombiner::removeFromWorkList(Instruction *I) {
|
||||
WorkList.end());
|
||||
}
|
||||
|
||||
|
||||
/// TryToSinkInstruction - Try to move the specified instruction from its
|
||||
/// current block into the beginning of DestBlock, which can only happen if it's
|
||||
/// safe to move the instruction past all of the instructions between it and the
|
||||
/// end of its block.
|
||||
static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
|
||||
assert(I->hasOneUse() && "Invariants didn't hold!");
|
||||
|
||||
// Cannot move control-flow-involving instructions.
|
||||
if (isa<PHINode>(I) || isa<InvokeInst>(I) || isa<CallInst>(I)) return false;
|
||||
|
||||
// Do not sink alloca instructions out of the entry block.
|
||||
if (isa<AllocaInst>(I) && I->getParent() == &DestBlock->getParent()->front())
|
||||
return false;
|
||||
|
||||
if (isa<LoadInst>(I)) return false;
|
||||
|
||||
BasicBlock::iterator InsertPos = DestBlock->begin();
|
||||
while (isa<PHINode>(InsertPos)) ++InsertPos;
|
||||
|
||||
BasicBlock *SrcBlock = I->getParent();
|
||||
DestBlock->getInstList().splice(InsertPos, SrcBlock->getInstList(), I);
|
||||
++NumSunkInst;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstCombiner::runOnFunction(Function &F) {
|
||||
bool Changed = false;
|
||||
TD = &getAnalysis<TargetData>();
|
||||
@ -4246,6 +4274,29 @@ bool InstCombiner::runOnFunction(Function &F) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if we can trivially sink this instruction to a successor basic block.
|
||||
if (I->hasOneUse()) {
|
||||
BasicBlock *BB = I->getParent();
|
||||
BasicBlock *UserParent = cast<Instruction>(I->use_back())->getParent();
|
||||
if (UserParent != BB) {
|
||||
bool UserIsSuccessor = false;
|
||||
// See if the user is one of our successors.
|
||||
for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
|
||||
if (*SI == UserParent) {
|
||||
UserIsSuccessor = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the user is one of our immediate successors, and if that successor
|
||||
// only has us as a predecessors (we'd have to split the critical edge
|
||||
// otherwise), we can keep going.
|
||||
if (UserIsSuccessor && !isa<PHINode>(I->use_back()) &&
|
||||
next(pred_begin(UserParent)) == pred_end(UserParent))
|
||||
// Okay, the CFG is simple enough, try to sink this instruction.
|
||||
Changed |= TryToSinkInstruction(I, UserParent);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have an instruction, try combining it to simplify it...
|
||||
if (Instruction *Result = visit(*I)) {
|
||||
++NumCombined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user