mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-21 02:24:22 +00:00
Disable indvar widening if arithmetics on the wider type are more expensive
Summary: IndVarSimplify should not widen an indvar if arithmetics on the wider indvar are more expensive than those on the narrower indvar. For instance, although NVPTX64 treats i64 as a legal type, an ADD on i64 is twice as expensive as that on i32, because the hardware needs to simulate a 64-bit integer using two 32-bit integers. Split from D6188, and based on D6195 which adds NVPTXTargetTransformInfo. Fixes PR21148. Test Plan: Added @indvar_32_bit that verifies we do not widen an indvar if the arithmetics on the wider type are more expensive. Reviewers: jholewinski, eliben, meheff, atrick Reviewed By: atrick Subscribers: jholewinski, llvm-commits Differential Revision: http://reviews.llvm.org/D6196 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221772 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -31,6 +31,7 @@
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
@ -69,11 +70,12 @@ static cl::opt<bool> ReduceLiveIVs("liv-reduce", cl::Hidden,
|
||||
|
||||
namespace {
|
||||
class IndVarSimplify : public LoopPass {
|
||||
LoopInfo *LI;
|
||||
ScalarEvolution *SE;
|
||||
DominatorTree *DT;
|
||||
const DataLayout *DL;
|
||||
TargetLibraryInfo *TLI;
|
||||
LoopInfo *LI;
|
||||
ScalarEvolution *SE;
|
||||
DominatorTree *DT;
|
||||
const DataLayout *DL;
|
||||
TargetLibraryInfo *TLI;
|
||||
const TargetTransformInfo *TTI;
|
||||
|
||||
SmallVector<WeakVH, 16> DeadInsts;
|
||||
bool Changed;
|
||||
@ -661,7 +663,7 @@ namespace {
|
||||
/// extended by this sign or zero extend operation. This is used to determine
|
||||
/// the final width of the IV before actually widening it.
|
||||
static void visitIVCast(CastInst *Cast, WideIVInfo &WI, ScalarEvolution *SE,
|
||||
const DataLayout *DL) {
|
||||
const DataLayout *DL, const TargetTransformInfo *TTI) {
|
||||
bool IsSigned = Cast->getOpcode() == Instruction::SExt;
|
||||
if (!IsSigned && Cast->getOpcode() != Instruction::ZExt)
|
||||
return;
|
||||
@ -671,6 +673,19 @@ static void visitIVCast(CastInst *Cast, WideIVInfo &WI, ScalarEvolution *SE,
|
||||
if (DL && !DL->isLegalInteger(Width))
|
||||
return;
|
||||
|
||||
// Cast is either an sext or zext up to this point.
|
||||
// We should not widen an indvar if arithmetics on the wider indvar are more
|
||||
// expensive than those on the narrower indvar. We check only the cost of ADD
|
||||
// because at least an ADD is required to increment the induction variable. We
|
||||
// could compute more comprehensively the cost of all instructions on the
|
||||
// induction variable when necessary.
|
||||
if (TTI &&
|
||||
TTI->getArithmeticInstrCost(Instruction::Add, Ty) >
|
||||
TTI->getArithmeticInstrCost(Instruction::Add,
|
||||
Cast->getOperand(0)->getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WI.WidestNativeType) {
|
||||
WI.WidestNativeType = SE->getEffectiveSCEVType(Ty);
|
||||
WI.IsSigned = IsSigned;
|
||||
@ -1187,14 +1202,16 @@ namespace {
|
||||
class IndVarSimplifyVisitor : public IVVisitor {
|
||||
ScalarEvolution *SE;
|
||||
const DataLayout *DL;
|
||||
const TargetTransformInfo *TTI;
|
||||
PHINode *IVPhi;
|
||||
|
||||
public:
|
||||
WideIVInfo WI;
|
||||
|
||||
IndVarSimplifyVisitor(PHINode *IV, ScalarEvolution *SCEV,
|
||||
const DataLayout *DL, const DominatorTree *DTree):
|
||||
SE(SCEV), DL(DL), IVPhi(IV) {
|
||||
const DataLayout *DL, const TargetTransformInfo *TTI,
|
||||
const DominatorTree *DTree)
|
||||
: SE(SCEV), DL(DL), TTI(TTI), IVPhi(IV) {
|
||||
DT = DTree;
|
||||
WI.NarrowIV = IVPhi;
|
||||
if (ReduceLiveIVs)
|
||||
@ -1202,7 +1219,9 @@ namespace {
|
||||
}
|
||||
|
||||
// Implement the interface used by simplifyUsersOfIV.
|
||||
void visitCast(CastInst *Cast) override { visitIVCast(Cast, WI, SE, DL); }
|
||||
void visitCast(CastInst *Cast) override {
|
||||
visitIVCast(Cast, WI, SE, DL, TTI);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1236,7 +1255,7 @@ void IndVarSimplify::SimplifyAndExtend(Loop *L,
|
||||
PHINode *CurrIV = LoopPhis.pop_back_val();
|
||||
|
||||
// Information about sign/zero extensions of CurrIV.
|
||||
IndVarSimplifyVisitor Visitor(CurrIV, SE, DL, DT);
|
||||
IndVarSimplifyVisitor Visitor(CurrIV, SE, DL, TTI, DT);
|
||||
|
||||
Changed |= simplifyUsersOfIV(CurrIV, SE, &LPM, DeadInsts, &Visitor);
|
||||
|
||||
@ -1895,6 +1914,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
|
||||
DL = DLP ? &DLP->getDataLayout() : nullptr;
|
||||
TLI = getAnalysisIfAvailable<TargetLibraryInfo>();
|
||||
TTI = getAnalysisIfAvailable<TargetTransformInfo>();
|
||||
|
||||
DeadInsts.clear();
|
||||
Changed = false;
|
||||
|
Reference in New Issue
Block a user