mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
Teach jump threading to clean up after itself, DCE and constfolding the
new instructions it simplifies. Because we're threading jumps on edges with constants coming in from PHI's, we inherently are exposing a lot more constants to the new block. Folding them and deleting dead conditions allows the cost model in jump threading to be more accurate as it iterates. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60327 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
11240d0fdd
commit
ef0c6744d5
@ -17,8 +17,10 @@
|
|||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/Analysis/ConstantFolding.h"
|
||||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
@ -51,10 +53,15 @@ namespace {
|
|||||||
/// revectored to the false side of the second if.
|
/// revectored to the false side of the second if.
|
||||||
///
|
///
|
||||||
class VISIBILITY_HIDDEN JumpThreading : public FunctionPass {
|
class VISIBILITY_HIDDEN JumpThreading : public FunctionPass {
|
||||||
|
TargetData *TD;
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass identification
|
static char ID; // Pass identification
|
||||||
JumpThreading() : FunctionPass(&ID) {}
|
JumpThreading() : FunctionPass(&ID) {}
|
||||||
|
|
||||||
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.addRequired<TargetData>();
|
||||||
|
}
|
||||||
|
|
||||||
bool runOnFunction(Function &F);
|
bool runOnFunction(Function &F);
|
||||||
bool ProcessBlock(BasicBlock *BB);
|
bool ProcessBlock(BasicBlock *BB);
|
||||||
void ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB);
|
void ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB);
|
||||||
@ -79,6 +86,7 @@ FunctionPass *llvm::createJumpThreadingPass() { return new JumpThreading(); }
|
|||||||
///
|
///
|
||||||
bool JumpThreading::runOnFunction(Function &F) {
|
bool JumpThreading::runOnFunction(Function &F) {
|
||||||
DOUT << "Jump threading on function '" << F.getNameStart() << "'\n";
|
DOUT << "Jump threading on function '" << F.getNameStart() << "'\n";
|
||||||
|
TD = &getAnalysis<TargetData>();
|
||||||
|
|
||||||
bool AnotherIteration = true, EverChanged = false;
|
bool AnotherIteration = true, EverChanged = false;
|
||||||
while (AnotherIteration) {
|
while (AnotherIteration) {
|
||||||
@ -679,7 +687,7 @@ void JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB,
|
|||||||
PN->addIncoming(IV, NewBB);
|
PN->addIncoming(IV, NewBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, NewBB is good to go. Update the terminator of PredBB to jump to
|
// Ok, NewBB is good to go. Update the terminator of PredBB to jump to
|
||||||
// NewBB instead of BB. This eliminates predecessors from BB, which requires
|
// NewBB instead of BB. This eliminates predecessors from BB, which requires
|
||||||
// us to simplify any PHI nodes in BB.
|
// us to simplify any PHI nodes in BB.
|
||||||
TerminatorInst *PredTerm = PredBB->getTerminator();
|
TerminatorInst *PredTerm = PredBB->getTerminator();
|
||||||
@ -688,4 +696,19 @@ void JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB,
|
|||||||
BB->removePredecessor(PredBB);
|
BB->removePredecessor(PredBB);
|
||||||
PredTerm->setSuccessor(i, NewBB);
|
PredTerm->setSuccessor(i, NewBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point, the IR is fully up to date and consistent. Do a quick scan
|
||||||
|
// over the new instructions and zap any that are constants or dead. This
|
||||||
|
// frequently happens because of phi translation.
|
||||||
|
BI = NewBB->begin();
|
||||||
|
for (BasicBlock::iterator E = NewBB->end(); BI != E; ) {
|
||||||
|
Instruction *Inst = BI++;
|
||||||
|
if (Constant *C = ConstantFoldInstruction(Inst, TD)) {
|
||||||
|
Inst->replaceAllUsesWith(C);
|
||||||
|
Inst->eraseFromParent();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecursivelyDeleteTriviallyDeadInstructions(Inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user