Skip to content

Commit

Permalink
[TLI] Add a new hook to TargetLowering to query the target if a load …
Browse files Browse the repository at this point in the history
…of a constant should be converted to simply the constant itself.

Before this patch we used getIntImmCost from TargetTransformInfo to determine if
a load of a constant should be converted to just a constant, but the threshold
for this was set to an arbitrary value. This value works well for the two
targets (X86 and ARM) that implement this target-hook, but it isn't
target-independent at all.

Now targets have the possibility to decide directly if this optimization should
be performed. The default value is set to false to preserve the current
behavior. The target hook has been moved to TargetLowering, which removed the
last use and need of TargetTransformInfo in SelectionDAG.

llvm-svn: 200271
  • Loading branch information
ributzka committed Jan 28, 2014
1 parent 18865db commit 659ce00
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 19 deletions.
1 change: 0 additions & 1 deletion llvm/include/llvm/Analysis/TargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ class TargetTransformInfo {
enum TargetCostConstants {
TCC_Free = 0, ///< Expected to fold away in lowering.
TCC_Basic = 1, ///< The cost of a typical 'add' instruction.
TCC_Load = 3,
TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86.
};

Expand Down
6 changes: 1 addition & 5 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class MDNode;
class SDDbgValue;
class TargetLowering;
class TargetSelectionDAGInfo;
class TargetTransformInfo;

class SDVTListNode : public FoldingSetNode {
friend struct FoldingSetTrait<SDVTListNode>;
Expand Down Expand Up @@ -169,7 +168,6 @@ void checkForCycles(const SelectionDAG *DAG);
class SelectionDAG {
const TargetMachine &TM;
const TargetSelectionDAGInfo &TSI;
const TargetTransformInfo *TTI;
const TargetLowering *TLI;
MachineFunction *MF;
LLVMContext *Context;
Expand Down Expand Up @@ -269,8 +267,7 @@ class SelectionDAG {
/// init - Prepare this SelectionDAG to process code in the given
/// MachineFunction.
///
void init(MachineFunction &mf, const TargetTransformInfo *TTI,
const TargetLowering *TLI);
void init(MachineFunction &mf, const TargetLowering *TLI);

/// clear - Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
Expand All @@ -281,7 +278,6 @@ class SelectionDAG {
const TargetMachine &getTarget() const { return TM; }
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
const TargetTransformInfo *getTargetTransformInfo() const { return TTI; }
LLVMContext *getContext() const {return Context; }

/// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
Expand Down
2 changes: 0 additions & 2 deletions llvm/include/llvm/CodeGen/SelectionDAGISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ namespace llvm {
class MachineInstr;
class TargetLowering;
class TargetLibraryInfo;
class TargetTransformInfo;
class FunctionLoweringInfo;
class ScheduleHazardRecognizer;
class GCFunctionInfo;
Expand All @@ -43,7 +42,6 @@ class SelectionDAGISel : public MachineFunctionPass {
public:
TargetMachine &TM;
const TargetLibraryInfo *LibInfo;
const TargetTransformInfo *TTI;
FunctionLoweringInfo *FuncInfo;
MachineFunction *MF;
MachineRegisterInfo *RegInfo;
Expand Down
9 changes: 9 additions & 0 deletions llvm/include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,15 @@ class TargetLoweringBase {
return false;
}

/// \brief Return true if it is beneficial to convert a load of a constant to
/// just the constant itself.
/// On some targets it might be more efficient to use a combination of
/// arithmetic instructions to materialize the constant instead of loading it
/// from a constant pool.
virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
Type *Ty) const {
return false;
}
//===--------------------------------------------------------------------===//
// Runtime Library hooks
//
Expand Down
12 changes: 4 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
Expand Down Expand Up @@ -887,18 +886,16 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {

// EntryNode could meaningfully have debug info if we can find it...
SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL)
: TM(tm), TSI(*tm.getSelectionDAGInfo()), TTI(0), TLI(0), OptLevel(OL),
: TM(tm), TSI(*tm.getSelectionDAGInfo()), TLI(0), OptLevel(OL),
EntryNode(ISD::EntryToken, 0, DebugLoc(), getVTList(MVT::Other)),
Root(getEntryNode()), NewNodesMustHaveLegalTypes(false),
UpdateListeners(0) {
AllNodes.push_back(&EntryNode);
DbgInfo = new SDDbgInfo();
}

void SelectionDAG::init(MachineFunction &mf, const TargetTransformInfo *tti,
const TargetLowering *tli) {
void SelectionDAG::init(MachineFunction &mf, const TargetLowering *tli) {
MF = &mf;
TTI = tti;
TLI = tli;
Context = &mf.getFunction()->getContext();
}
Expand Down Expand Up @@ -3575,9 +3572,8 @@ static SDValue getMemsetStringVal(EVT VT, SDLoc dl, SelectionDAG &DAG,

// If the "cost" of materializing the integer immediate is less than the cost
// of a load, then it is cost effective to turn the load into the immediate.
const TargetTransformInfo *TTI = DAG.getTargetTransformInfo();
if (TTI->getIntImmCost(Val, VT.getTypeForEVT(*DAG.getContext())) <
TargetTransformInfo::TCC_Load)
Type *Ty = VT.getTypeForEVT(*DAG.getContext());
if (TLI.shouldConvertConstantLoadToIntImm(Val, Ty))
return DAG.getConstant(Val, VT);
return SDValue(0, 0);
}
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/GCMetadata.h"
Expand Down Expand Up @@ -400,7 +399,6 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
RegInfo = &MF->getRegInfo();
AA = &getAnalysis<AliasAnalysis>();
LibInfo = &getAnalysis<TargetLibraryInfo>();
TTI = getAnalysisIfAvailable<TargetTransformInfo>();
GFI = Fn.hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) : 0;

TargetSubtargetInfo &ST =
Expand All @@ -418,7 +416,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {

SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);

CurDAG->init(*MF, TTI, TLI);
CurDAG->init(*MF, TLI);
FuncInfo->set(Fn, *MF);

if (UseMBPI && OptLevel != CodeGenOpt::None)
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11199,3 +11199,15 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,

return false;
}

/// \brief Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself.
bool ARMTargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
Type *Ty) const {
assert(Ty->isIntegerTy());

unsigned Bits = Ty->getPrimitiveSizeInBits();
if (Bits == 0 || Bits > 32)
return false;
return true;
}
6 changes: 6 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,12 @@ namespace llvm {
virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
const CallInst &I,
unsigned Intrinsic) const;

/// \brief Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself.
virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
Type *Ty) const;

protected:
std::pair<const TargetRegisterClass*, uint8_t>
findRepresentativeClass(MVT VT) const;
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3570,6 +3570,18 @@ bool X86TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
return false;
}

/// \brief Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself.
bool X86TargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
Type *Ty) const {
assert(Ty->isIntegerTy());

unsigned BitSize = Ty->getPrimitiveSizeInBits();
if (BitSize == 0 || BitSize > 64)
return false;
return true;
}

/// isUndefOrInRange - Return true if Val is undef or if its value falls within
/// the specified range (L, H].
static bool isUndefOrInRange(int Val, int Low, int Hi) {
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/X86/X86ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,11 @@ namespace llvm {
return isTargetFTOL() && VT == MVT::i64;
}

/// \brief Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself.
virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
Type *Ty) const;

/// createFastISel - This method returns a target specific FastISel object,
/// or null if the target does not support "fast" ISel.
virtual FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
Expand Down

0 comments on commit 659ce00

Please sign in to comment.