Change ConstantSDNode and ConstantFPSDNode to use ConstantInt* and

ConstantFP* instead of APInt and APFloat directly.

This reduces the amount of time to create ConstantSDNode
and ConstantFPSDNode nodes when ConstantInt* and ConstantFP*
respectively are already available, as is the case in
SelectionDAGBuild.cpp. Also, it reduces the amount of time
to legalize constants into constant pools, and the amount of
time to add ConstantFP operands to MachineInstrs, due to
eliminating ConstantInt::get and ConstantFP::get calls.

It increases the amount of work needed to create new constants
in cases where the client doesn't already have a ConstantInt*
or ConstantFP*, such as legalize expanding 64-bit integer constants
to 32-bit constants. And it adds a layer of indirection for the
accessor methods. But these appear to be outweight by the benefits
in most cases.

It will also make it easier to make ConstantSDNode and
ConstantFPNode more consistent with ConstantInt and ConstantFP.

llvm-svn: 56162
This commit is contained in:
Dan Gohman 2008-09-12 18:08:03 +00:00
parent 1f3ab86804
commit ec270fb640
10 changed files with 53 additions and 37 deletions

View File

@ -52,7 +52,7 @@ public:
return *this; return *this;
} }
const MachineInstrBuilder &addFPImm(ConstantFP *Val) const { const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
MI->addOperand(MachineOperand::CreateFPImm(Val)); MI->addOperand(MachineOperand::CreateFPImm(Val));
return *this; return *this;
} }

View File

@ -86,7 +86,7 @@ private:
/// Contents union - This contains the payload for the various operand types. /// Contents union - This contains the payload for the various operand types.
union { union {
MachineBasicBlock *MBB; // For MO_MachineBasicBlock. MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
ConstantFP *CFP; // For MO_FPImmediate. const ConstantFP *CFP; // For MO_FPImmediate.
int64_t ImmVal; // For MO_Immediate. int64_t ImmVal; // For MO_Immediate.
struct { // For MO_Register. struct { // For MO_Register.
@ -252,7 +252,7 @@ public:
return Contents.ImmVal; return Contents.ImmVal;
} }
ConstantFP *getFPImm() const { const ConstantFP *getFPImm() const {
assert(isFPImmediate() && "Wrong MachineOperand accessor"); assert(isFPImmediate() && "Wrong MachineOperand accessor");
return Contents.CFP; return Contents.CFP;
} }
@ -340,7 +340,7 @@ public:
return Op; return Op;
} }
static MachineOperand CreateFPImm(ConstantFP *CFP) { static MachineOperand CreateFPImm(const ConstantFP *CFP) {
MachineOperand Op(MachineOperand::MO_FPImmediate); MachineOperand Op(MachineOperand::MO_FPImmediate);
Op.Contents.CFP = CFP; Op.Contents.CFP = CFP;
return Op; return Op;

View File

@ -231,6 +231,7 @@ public:
// //
SDValue getConstant(uint64_t Val, MVT VT, bool isTarget = false); SDValue getConstant(uint64_t Val, MVT VT, bool isTarget = false);
SDValue getConstant(const APInt &Val, MVT VT, bool isTarget = false); SDValue getConstant(const APInt &Val, MVT VT, bool isTarget = false);
SDValue getConstant(const ConstantInt &Val, MVT VT, bool isTarget = false);
SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false); SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false);
SDValue getTargetConstant(uint64_t Val, MVT VT) { SDValue getTargetConstant(uint64_t Val, MVT VT) {
return getConstant(Val, VT, true); return getConstant(Val, VT, true);
@ -238,14 +239,21 @@ public:
SDValue getTargetConstant(const APInt &Val, MVT VT) { SDValue getTargetConstant(const APInt &Val, MVT VT) {
return getConstant(Val, VT, true); return getConstant(Val, VT, true);
} }
SDValue getTargetConstant(const ConstantInt &Val, MVT VT) {
return getConstant(Val, VT, true);
}
SDValue getConstantFP(double Val, MVT VT, bool isTarget = false); SDValue getConstantFP(double Val, MVT VT, bool isTarget = false);
SDValue getConstantFP(const APFloat& Val, MVT VT, bool isTarget = false); SDValue getConstantFP(const APFloat& Val, MVT VT, bool isTarget = false);
SDValue getConstantFP(const ConstantFP &CF, MVT VT, bool isTarget = false);
SDValue getTargetConstantFP(double Val, MVT VT) { SDValue getTargetConstantFP(double Val, MVT VT) {
return getConstantFP(Val, VT, true); return getConstantFP(Val, VT, true);
} }
SDValue getTargetConstantFP(const APFloat& Val, MVT VT) { SDValue getTargetConstantFP(const APFloat& Val, MVT VT) {
return getConstantFP(Val, VT, true); return getConstantFP(Val, VT, true);
} }
SDValue getTargetConstantFP(const ConstantFP &Val, MVT VT) {
return getConstantFP(Val, VT, true);
}
SDValue getGlobalAddress(const GlobalValue *GV, MVT VT, SDValue getGlobalAddress(const GlobalValue *GV, MVT VT,
int offset = 0, bool isTargetGA = false); int offset = 0, bool isTargetGA = false);
SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT, SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT,

View File

@ -20,11 +20,10 @@
#define LLVM_CODEGEN_SELECTIONDAGNODES_H #define LLVM_CODEGEN_SELECTIONDAGNODES_H
#include "llvm/Value.h" #include "llvm/Value.h"
#include "llvm/Constants.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ValueTypes.h"
@ -1704,28 +1703,27 @@ class AtomicSDNode : public MemSDNode {
}; };
class ConstantSDNode : public SDNode { class ConstantSDNode : public SDNode {
APInt Value; const ConstantInt *Value;
virtual void ANCHOR(); // Out-of-line virtual method to give class a home. virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
protected: protected:
friend class SelectionDAG; friend class SelectionDAG;
ConstantSDNode(bool isTarget, const APInt &val, MVT VT) ConstantSDNode(bool isTarget, const ConstantInt *val, MVT VT)
: SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, getSDVTList(VT)), : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, getSDVTList(VT)),
Value(val) { Value(val) {
} }
public: public:
const APInt &getAPIntValue() const { return Value; } const ConstantInt *getConstantIntValue() const { return Value; }
uint64_t getZExtValue() const { return Value.getZExtValue(); } const APInt &getAPIntValue() const { return Value->getValue(); }
uint64_t getZExtValue() const { return Value->getZExtValue(); }
int64_t getSignExtended() const { int64_t getSignExtended() const {
unsigned Bits = getValueType(0).getSizeInBits(); unsigned Bits = getValueType(0).getSizeInBits();
return ((int64_t)Value.getZExtValue() << (64-Bits)) >> (64-Bits); return ((int64_t)getZExtValue() << (64-Bits)) >> (64-Bits);
} }
bool isNullValue() const { return Value == 0; } bool isNullValue() const { return Value->isNullValue(); }
bool isAllOnesValue() const { bool isAllOnesValue() const { return Value->isAllOnesValue(); }
return Value == getValueType(0).getIntegerVTBitMask();
}
static bool classof(const ConstantSDNode *) { return true; } static bool classof(const ConstantSDNode *) { return true; }
static bool classof(const SDNode *N) { static bool classof(const SDNode *N) {
@ -1735,17 +1733,18 @@ public:
}; };
class ConstantFPSDNode : public SDNode { class ConstantFPSDNode : public SDNode {
APFloat Value; const ConstantFP *Value;
virtual void ANCHOR(); // Out-of-line virtual method to give class a home. virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
protected: protected:
friend class SelectionDAG; friend class SelectionDAG;
ConstantFPSDNode(bool isTarget, const APFloat& val, MVT VT) ConstantFPSDNode(bool isTarget, const ConstantFP *val, MVT VT)
: SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
getSDVTList(VT)), Value(val) { getSDVTList(VT)), Value(val) {
} }
public: public:
const APFloat& getValueAPF() const { return Value; } const APFloat& getValueAPF() const { return Value->getValueAPF(); }
const ConstantFP *getConstantFPValue() const { return Value; }
/// isExactlyValue - We don't rely on operator== working on double values, as /// isExactlyValue - We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
@ -1757,10 +1756,11 @@ public:
/// have to duplicate its logic everywhere it's called. /// have to duplicate its logic everywhere it's called.
bool isExactlyValue(double V) const { bool isExactlyValue(double V) const {
// convert is not supported on this type // convert is not supported on this type
if (&Value.getSemantics() == &APFloat::PPCDoubleDouble) if (&Value->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
return false; return false;
APFloat Tmp(V); APFloat Tmp(V);
Tmp.convert(Value.getSemantics(), APFloat::rmNearestTiesToEven); Tmp.convert(Value->getValueAPF().getSemantics(),
APFloat::rmNearestTiesToEven);
return isExactlyValue(Tmp); return isExactlyValue(Tmp);
} }
bool isExactlyValue(const APFloat& V) const; bool isExactlyValue(const APFloat& V) const;

View File

@ -4021,7 +4021,7 @@ SDValue DAGCombiner::visitFP_ROUND_INREG(SDNode *N) {
// fold (fp_round_inreg c1fp) -> c1fp // fold (fp_round_inreg c1fp) -> c1fp
if (N0CFP) { if (N0CFP) {
SDValue Round = DAG.getConstantFP(N0CFP->getValueAPF(), EVT); SDValue Round = DAG.getConstantFP(*N0CFP->getConstantFPValue(), EVT);
return DAG.getNode(ISD::FP_EXTEND, VT, Round); return DAG.getNode(ISD::FP_EXTEND, VT, Round);
} }
return SDValue(); return SDValue();

View File

@ -442,7 +442,7 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
// an FP extending load is the same cost as a normal load (such as on the x87 // an FP extending load is the same cost as a normal load (such as on the x87
// fp stack or PPC FP unit). // fp stack or PPC FP unit).
MVT VT = CFP->getValueType(0); MVT VT = CFP->getValueType(0);
ConstantFP *LLVMC = ConstantFP::get(CFP->getValueAPF()); ConstantFP *LLVMC = const_cast<ConstantFP*>(CFP->getConstantFPValue());
if (!UseCP) { if (!UseCP) {
if (VT!=MVT::f64 && VT!=MVT::f32) if (VT!=MVT::f64 && VT!=MVT::f32)
assert(0 && "Invalid type expansion"); assert(0 && "Invalid type expansion");
@ -4984,10 +4984,10 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
for (unsigned i = 0, e = NumElems; i != e; ++i) { for (unsigned i = 0, e = NumElems; i != e; ++i) {
if (ConstantFPSDNode *V = if (ConstantFPSDNode *V =
dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) { dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
CV.push_back(ConstantFP::get(V->getValueAPF())); CV.push_back(const_cast<ConstantFP *>(V->getConstantFPValue()));
} else if (ConstantSDNode *V = } else if (ConstantSDNode *V =
dyn_cast<ConstantSDNode>(Node->getOperand(i))) { dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
CV.push_back(ConstantInt::get(V->getAPIntValue())); CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
} else { } else {
assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
const Type *OpNTy = const Type *OpNTy =

View File

@ -256,7 +256,7 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op,
} else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) { } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateImm(C->getZExtValue())); MI->addOperand(MachineOperand::CreateImm(C->getZExtValue()));
} else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) { } else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) {
ConstantFP *CFP = ConstantFP::get(F->getValueAPF()); const ConstantFP *CFP = F->getConstantFPValue();
MI->addOperand(MachineOperand::CreateFPImm(CFP)); MI->addOperand(MachineOperand::CreateFPImm(CFP));
} else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) { } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateReg(R->getReg(), false)); MI->addOperand(MachineOperand::CreateReg(R->getReg(), false));

View File

@ -69,7 +69,7 @@ SelectionDAG::DAGUpdateListener::~DAGUpdateListener() {}
/// As such, this method can be used to do an exact bit-for-bit comparison of /// As such, this method can be used to do an exact bit-for-bit comparison of
/// two floating point values. /// two floating point values.
bool ConstantFPSDNode::isExactlyValue(const APFloat& V) const { bool ConstantFPSDNode::isExactlyValue(const APFloat& V) const {
return Value.bitwiseIsEqual(V); return getValueAPF().bitwiseIsEqual(V);
} }
bool ConstantFPSDNode::isValueValidForType(MVT VT, bool ConstantFPSDNode::isValueValidForType(MVT VT,
@ -367,11 +367,11 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {
break; break;
case ISD::TargetConstant: case ISD::TargetConstant:
case ISD::Constant: case ISD::Constant:
ID.Add(cast<ConstantSDNode>(N)->getAPIntValue()); ID.AddPointer(cast<ConstantSDNode>(N)->getConstantIntValue());
break; break;
case ISD::TargetConstantFP: case ISD::TargetConstantFP:
case ISD::ConstantFP: { case ISD::ConstantFP: {
ID.Add(cast<ConstantFPSDNode>(N)->getValueAPF()); ID.AddPointer(cast<ConstantFPSDNode>(N)->getConstantFPValue());
break; break;
} }
case ISD::TargetGlobalAddress: case ISD::TargetGlobalAddress:
@ -861,6 +861,10 @@ SDValue SelectionDAG::getConstant(uint64_t Val, MVT VT, bool isT) {
} }
SDValue SelectionDAG::getConstant(const APInt &Val, MVT VT, bool isT) { SDValue SelectionDAG::getConstant(const APInt &Val, MVT VT, bool isT) {
return getConstant(*ConstantInt::get(Val), VT, isT);
}
SDValue SelectionDAG::getConstant(const ConstantInt &Val, MVT VT, bool isT) {
assert(VT.isInteger() && "Cannot create FP integer constant!"); assert(VT.isInteger() && "Cannot create FP integer constant!");
MVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT; MVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT;
@ -870,7 +874,7 @@ SDValue SelectionDAG::getConstant(const APInt &Val, MVT VT, bool isT) {
unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant; unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;
FoldingSetNodeID ID; FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
ID.Add(Val); ID.AddPointer(&Val);
void *IP = 0; void *IP = 0;
SDNode *N = NULL; SDNode *N = NULL;
if ((N = CSEMap.FindNodeOrInsertPos(ID, IP))) if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
@ -878,7 +882,7 @@ SDValue SelectionDAG::getConstant(const APInt &Val, MVT VT, bool isT) {
return SDValue(N, 0); return SDValue(N, 0);
if (!N) { if (!N) {
N = NodeAllocator.Allocate<ConstantSDNode>(); N = NodeAllocator.Allocate<ConstantSDNode>();
new (N) ConstantSDNode(isT, Val, EltVT); new (N) ConstantSDNode(isT, &Val, EltVT);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);
AllNodes.push_back(N); AllNodes.push_back(N);
} }
@ -898,6 +902,10 @@ SDValue SelectionDAG::getIntPtrConstant(uint64_t Val, bool isTarget) {
SDValue SelectionDAG::getConstantFP(const APFloat& V, MVT VT, bool isTarget) { SDValue SelectionDAG::getConstantFP(const APFloat& V, MVT VT, bool isTarget) {
return getConstantFP(*ConstantFP::get(V), VT, isTarget);
}
SDValue SelectionDAG::getConstantFP(const ConstantFP& V, MVT VT, bool isTarget){
assert(VT.isFloatingPoint() && "Cannot create integer FP constant!"); assert(VT.isFloatingPoint() && "Cannot create integer FP constant!");
MVT EltVT = MVT EltVT =
@ -909,7 +917,7 @@ SDValue SelectionDAG::getConstantFP(const APFloat& V, MVT VT, bool isTarget) {
unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP; unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;
FoldingSetNodeID ID; FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
ID.Add(V); ID.AddPointer(&V);
void *IP = 0; void *IP = 0;
SDNode *N = NULL; SDNode *N = NULL;
if ((N = CSEMap.FindNodeOrInsertPos(ID, IP))) if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
@ -917,7 +925,7 @@ SDValue SelectionDAG::getConstantFP(const APFloat& V, MVT VT, bool isTarget) {
return SDValue(N, 0); return SDValue(N, 0);
if (!N) { if (!N) {
N = NodeAllocator.Allocate<ConstantFPSDNode>(); N = NodeAllocator.Allocate<ConstantFPSDNode>();
new (N) ConstantFPSDNode(isTarget, V, EltVT); new (N) ConstantFPSDNode(isTarget, &V, EltVT);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);
AllNodes.push_back(N); AllNodes.push_back(N);
} }

View File

@ -794,7 +794,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
MVT VT = TLI.getValueType(V->getType(), true); MVT VT = TLI.getValueType(V->getType(), true);
if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) if (ConstantInt *CI = dyn_cast<ConstantInt>(C))
return N = DAG.getConstant(CI->getValue(), VT); return N = DAG.getConstant(*CI, VT);
if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
return N = DAG.getGlobalAddress(GV, VT); return N = DAG.getGlobalAddress(GV, VT);
@ -803,7 +803,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
return N = DAG.getConstant(0, TLI.getPointerTy()); return N = DAG.getConstant(0, TLI.getPointerTy());
if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) if (ConstantFP *CFP = dyn_cast<ConstantFP>(C))
return N = DAG.getConstantFP(CFP->getValueAPF(), VT); return N = DAG.getConstantFP(*CFP, VT);
if (isa<UndefValue>(C) && !isa<VectorType>(V->getType()) && if (isa<UndefValue>(C) && !isa<VectorType>(V->getType()) &&
!V->getType()->isAggregateType()) !V->getType()->isAggregateType())

View File

@ -792,9 +792,9 @@ public:
assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
std::string TmpVar = "Tmp" + utostr(ResNo); std::string TmpVar = "Tmp" + utostr(ResNo);
emitCode("SDValue " + TmpVar + emitCode("SDValue " + TmpVar +
" = CurDAG->getTargetConstantFP(cast<ConstantFPSDNode>(" + " = CurDAG->getTargetConstantFP(*cast<ConstantFPSDNode>(" +
Val + ")->getValueAPF(), cast<ConstantFPSDNode>(" + Val + Val + ")->getConstantFPValue(), cast<ConstantFPSDNode>(" +
")->getValueType(0));"); Val + ")->getValueType(0));");
// Add Tmp<ResNo> to VariableMap, so that we don't multiply select this // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
// value if used multiple times by this pattern result. // value if used multiple times by this pattern result.
Val = TmpVar; Val = TmpVar;