mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 04:33:40 +00:00
If both result of the {s|z}xt and its source are live out, rewrite all uses of the source with result of extension.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44643 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
22d806605e
commit
bdcb726fca
@ -28,11 +28,17 @@
|
|||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
cl::opt<bool> OptExtUses("optimize-ext-uses",
|
||||||
|
cl::init(false), cl::Hidden);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass {
|
class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass {
|
||||||
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
||||||
@ -52,6 +58,7 @@ namespace {
|
|||||||
bool OptimizeLoadStoreInst(Instruction *I, Value *Addr,
|
bool OptimizeLoadStoreInst(Instruction *I, Value *Addr,
|
||||||
const Type *AccessTy,
|
const Type *AccessTy,
|
||||||
DenseMap<Value*,Value*> &SunkAddrs);
|
DenseMap<Value*,Value*> &SunkAddrs);
|
||||||
|
bool OptimizeExtUses(Instruction *I);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,6 +920,61 @@ bool CodeGenPrepare::OptimizeLoadStoreInst(Instruction *LdStInst, Value *Addr,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CodeGenPrepare::OptimizeExtUses(Instruction *I) {
|
||||||
|
BasicBlock *DefBB = I->getParent();
|
||||||
|
|
||||||
|
// If both result of the {s|z}xt and its source are live out, rewrite all
|
||||||
|
// other uses of the source with result of extension.
|
||||||
|
Value *Src = I->getOperand(0);
|
||||||
|
if (Src->hasOneUse())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool DefIsLiveOut = false;
|
||||||
|
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
||||||
|
UI != E; ++UI) {
|
||||||
|
Instruction *User = cast<Instruction>(*UI);
|
||||||
|
|
||||||
|
// Figure out which BB this ext is used in.
|
||||||
|
BasicBlock *UserBB = User->getParent();
|
||||||
|
if (UserBB == DefBB) continue;
|
||||||
|
DefIsLiveOut = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!DefIsLiveOut)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// InsertedTruncs - Only insert one trunc in each block once.
|
||||||
|
DenseMap<BasicBlock*, Instruction*> InsertedTruncs;
|
||||||
|
|
||||||
|
bool MadeChange = false;
|
||||||
|
for (Value::use_iterator UI = Src->use_begin(), E = Src->use_end();
|
||||||
|
UI != E; ++UI) {
|
||||||
|
Use &TheUse = UI.getUse();
|
||||||
|
Instruction *User = cast<Instruction>(*UI);
|
||||||
|
|
||||||
|
// Figure out which BB this ext is used in.
|
||||||
|
BasicBlock *UserBB = User->getParent();
|
||||||
|
if (UserBB == DefBB) continue;
|
||||||
|
|
||||||
|
// Both src and def are live in this block. Rewrite the use.
|
||||||
|
Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
|
||||||
|
|
||||||
|
if (!InsertedTrunc) {
|
||||||
|
BasicBlock::iterator InsertPt = UserBB->begin();
|
||||||
|
while (isa<PHINode>(InsertPt)) ++InsertPt;
|
||||||
|
|
||||||
|
InsertedTrunc = new TruncInst(I, Src->getType(), "", InsertPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace a use of the {s|z}ext source with a use of the result.
|
||||||
|
TheUse = InsertedTrunc;
|
||||||
|
|
||||||
|
MadeChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MadeChange;
|
||||||
|
}
|
||||||
|
|
||||||
// In this pass we look for GEP and cast instructions that are used
|
// In this pass we look for GEP and cast instructions that are used
|
||||||
// across basic blocks and rewrite them to improve basic-block-at-a-time
|
// across basic blocks and rewrite them to improve basic-block-at-a-time
|
||||||
// selection.
|
// selection.
|
||||||
@ -948,8 +1010,14 @@ bool CodeGenPrepare::OptimizeBlock(BasicBlock &BB) {
|
|||||||
if (isa<Constant>(CI->getOperand(0)))
|
if (isa<Constant>(CI->getOperand(0)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (TLI)
|
bool Change = false;
|
||||||
MadeChange |= OptimizeNoopCopyExpression(CI, *TLI);
|
if (TLI) {
|
||||||
|
Change = OptimizeNoopCopyExpression(CI, *TLI);
|
||||||
|
MadeChange |= Change;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptExtUses && !Change && (isa<ZExtInst>(I) || isa<SExtInst>(I)))
|
||||||
|
MadeChange |= OptimizeExtUses(I);
|
||||||
} else if (CmpInst *CI = dyn_cast<CmpInst>(I)) {
|
} else if (CmpInst *CI = dyn_cast<CmpInst>(I)) {
|
||||||
MadeChange |= OptimizeCmpExpression(CI);
|
MadeChange |= OptimizeCmpExpression(CI);
|
||||||
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user