25 #define DEBUG_TYPE "legalize-types"
31 void DAGTypeLegalizer::PerformExpensiveChecks() {
78 if (Node.getNodeId() ==
NewNode)
81 for (
unsigned i = 0, e = Node.getNumValues();
i != e; ++
i) {
86 if (ReplacedValues.find(Res) != ReplacedValues.end()) {
91 if (UI.getUse().getResNo() ==
i)
93 "Remapped value has non-trivial use!");
97 SDValue NewVal = ReplacedValues[Res];
99 while (I != ReplacedValues.end()) {
101 I = ReplacedValues.find(NewVal);
104 "ReplacedValues maps to a new node!");
106 if (PromotedIntegers.find(Res) != PromotedIntegers.end())
108 if (SoftenedFloats.find(Res) != SoftenedFloats.end())
110 if (ScalarizedVectors.find(Res) != ScalarizedVectors.end())
112 if (ExpandedIntegers.find(Res) != ExpandedIntegers.end())
114 if (ExpandedFloats.find(Res) != ExpandedFloats.end())
116 if (SplitVectors.find(Res) != SplitVectors.end())
118 if (WidenedVectors.find(Res) != WidenedVectors.end())
120 if (PromotedFloats.find(Res) != PromotedFloats.end())
127 if ((Node.getNodeId() ==
NewNode && Mapped > 1) ||
128 (Node.getNodeId() !=
NewNode && Mapped != 0)) {
129 dbgs() <<
"Unprocessed value in a map!";
132 }
else if (isTypeLegal(Res.getValueType()) || IgnoreNodeResults(&Node)) {
134 dbgs() <<
"Value with legal type was transformed!";
139 dbgs() <<
"Processed value not in any map!";
141 }
else if (Mapped & (Mapped - 1)) {
142 dbgs() <<
"Value in multiple maps!";
149 dbgs() <<
" ReplacedValues";
151 dbgs() <<
" PromotedIntegers";
153 dbgs() <<
" SoftenedFloats";
155 dbgs() <<
" ScalarizedVectors";
157 dbgs() <<
" ExpandedIntegers";
159 dbgs() <<
" ExpandedFloats";
161 dbgs() <<
" SplitVectors";
163 dbgs() <<
" WidenedVectors";
165 dbgs() <<
" PromotedFloats";
173 for (
unsigned i = 0, e = NewNodes.
size();
i != e; ++
i) {
177 assert(UI->getNodeId() ==
NewNode &&
"NewNode used by non-NewNode!");
185 bool Changed =
false;
201 if (Node.getNumOperands() == 0) {
203 Worklist.push_back(&Node);
210 while (!Worklist.empty()) {
211 #ifndef EXPENSIVE_CHECKS
214 PerformExpensiveChecks();
216 SDNode *N = Worklist.back();
219 "Node should be ready if on worklist!");
221 if (IgnoreNodeResults(N))
226 for (
unsigned i = 0, NumResults = N->
getNumValues();
i < NumResults; ++
i) {
228 switch (getTypeAction(ResultVT)) {
237 PromoteIntegerResult(N,
i);
241 ExpandIntegerResult(N,
i);
245 Changed = SoftenFloatResult(N,
i);
249 assert(isLegalInHWReg(ResultVT) &&
250 "Unchanged SoftenFloatResult should be legal in register!");
253 ExpandFloatResult(N,
i);
257 ScalarizeVectorResult(N,
i);
261 SplitVectorResult(N,
i);
265 WidenVectorResult(N,
i);
269 PromoteFloatResult(N,
i);
280 bool NeedsReanalyzing =
false;
282 for (i = 0; i != NumOperands; ++
i) {
287 switch (getTypeAction(OpVT)) {
294 NeedsReanalyzing = PromoteIntegerOperand(N, i);
298 NeedsReanalyzing = ExpandIntegerOperand(N, i);
302 NeedsReanalyzing = SoftenFloatOperand(N, i);
306 NeedsReanalyzing = ExpandFloatOperand(N, i);
310 NeedsReanalyzing = ScalarizeVectorOperand(N, i);
314 NeedsReanalyzing = SplitVectorOperand(N, i);
318 NeedsReanalyzing = WidenVectorOperand(N, i);
322 NeedsReanalyzing = PromoteFloatOperand(N, i);
332 if (NeedsReanalyzing) {
337 SDNode *M = AnalyzeNewNode(N);
345 "Node morphing changed the number of results!");
356 if (i == NumOperands) {
379 Worklist.push_back(User);
397 Worklist.push_back(User);
401 #ifndef EXPENSIVE_CHECKS
404 PerformExpensiveChecks();
427 if (!IgnoreNodeResults(&Node))
428 for (
unsigned i = 0, NumVals = Node.getNumValues();
i < NumVals; ++
i)
429 if (!isTypeLegal(Node.getValueType(
i)) &&
431 dbgs() <<
"Result type " <<
i <<
" illegal: ";
437 for (
unsigned i = 0, NumOps = Node.getNumOperands();
i < NumOps; ++
i)
438 if (!IgnoreNodeResults(Node.getOperand(
i).getNode()) &&
439 !isTypeLegal(Node.getOperand(
i).getValueType()) &&
441 dbgs() <<
"Operand type " <<
i <<
" illegal: ";
442 Node.getOperand(
i).dump();
447 if (Node.getNodeId() ==
NewNode)
448 dbgs() <<
"New node not analyzed?\n";
450 dbgs() <<
"Unanalyzed node not noticed?\n";
451 else if (Node.getNodeId() > 0)
452 dbgs() <<
"Operand not processed?\n";
454 dbgs() <<
"Not added to worklist?\n";
459 Node.dump(&DAG);
dbgs() <<
"\n";
491 std::vector<SDValue> NewOps;
492 unsigned NumProcessed = 0;
502 if (!NewOps.empty()) {
504 NewOps.push_back(Op);
505 }
else if (Op != OrigOp) {
508 NewOps.push_back(Op);
513 if (!NewOps.empty()) {
537 Worklist.push_back(N);
544 void DAGTypeLegalizer::AnalyzeNewValue(
SDValue &Val) {
564 void DAGTypeLegalizer::ExpungeNode(
SDNode *N) {
571 if (ReplacedValues.find(
SDValue(N, i)) != ReplacedValues.end())
580 E = PromotedIntegers.end(); I !=
E; ++
I) {
581 assert(I->first.getNode() !=
N);
582 RemapValue(I->second);
586 E = SoftenedFloats.end(); I !=
E; ++
I) {
587 assert(I->first.getNode() !=
N);
588 RemapValue(I->second);
592 E = ScalarizedVectors.end(); I !=
E; ++
I) {
593 assert(I->first.getNode() !=
N);
594 RemapValue(I->second);
598 E = WidenedVectors.end(); I !=
E; ++
I) {
599 assert(I->first.getNode() !=
N);
600 RemapValue(I->second);
604 I = ExpandedIntegers.begin(),
E = ExpandedIntegers.end(); I !=
E; ++
I){
605 assert(I->first.getNode() !=
N);
606 RemapValue(I->second.first);
607 RemapValue(I->second.second);
611 I = ExpandedFloats.begin(),
E = ExpandedFloats.end(); I !=
E; ++
I) {
612 assert(I->first.getNode() !=
N);
613 RemapValue(I->second.first);
614 RemapValue(I->second.second);
618 I = SplitVectors.begin(),
E = SplitVectors.end(); I !=
E; ++
I) {
619 assert(I->first.getNode() !=
N);
620 RemapValue(I->second.first);
621 RemapValue(I->second.second);
625 E = ReplacedValues.end(); I !=
E; ++
I)
626 RemapValue(I->second);
629 ReplacedValues.erase(
SDValue(N, i));
634 void DAGTypeLegalizer::RemapValue(
SDValue &N) {
636 if (I != ReplacedValues.end()) {
639 RemapValue(I->second);
658 DTL(dtl), NodesToAnalyze(nta) {}
663 "Invalid node ID for RAUW deletion!");
666 assert(E &&
"Node not replaced?");
667 DTL.NoteDeletion(N, E);
671 NodesToAnalyze.remove(N);
678 NodesToAnalyze.insert(E);
681 void NodeUpdated(
SDNode *N)
override {
687 "Invalid node ID for RAUW deletion!");
689 NodesToAnalyze.insert(N);
697 void DAGTypeLegalizer::ReplaceValueWith(
SDValue From,
SDValue To) {
707 NodeUpdateListener NUL(*
this, NodesToAnalyze);
713 ReplacedValues[From] = To;
716 while (!NodesToAnalyze.
empty()) {
726 SDNode *M = AnalyzeNewNode(N);
732 "Node morphing changed the number of results!");
743 ReplacedValues[OldVal] = NewVal;
754 void DAGTypeLegalizer::SetPromotedInteger(
SDValue Op,
SDValue Result) {
757 "Invalid type for promoted integer");
758 AnalyzeNewValue(Result);
765 void DAGTypeLegalizer::SetSoftenedFloat(
SDValue Op,
SDValue Result) {
772 "Invalid type for softened float");
773 AnalyzeNewValue(Result);
782 "Node is already converted to integer!");
786 void DAGTypeLegalizer::SetPromotedFloat(
SDValue Op,
SDValue Result) {
789 "Invalid type for promoted float");
790 AnalyzeNewValue(Result);
797 void DAGTypeLegalizer::SetScalarizedVector(
SDValue Op,
SDValue Result) {
802 "Invalid type for scalarized vector");
803 AnalyzeNewValue(Result);
805 SDValue &OpEntry = ScalarizedVectors[
Op];
812 std::pair<SDValue, SDValue> &Entry = ExpandedIntegers[
Op];
813 RemapValue(Entry.first);
814 RemapValue(Entry.second);
815 assert(Entry.first.getNode() &&
"Operand isn't expanded");
825 "Invalid type for expanded integer");
831 std::pair<SDValue, SDValue> &Entry = ExpandedIntegers[
Op];
832 assert(!Entry.first.getNode() &&
"Node already expanded");
839 std::pair<SDValue, SDValue> &Entry = ExpandedFloats[
Op];
840 RemapValue(Entry.first);
841 RemapValue(Entry.second);
842 assert(Entry.first.getNode() &&
"Operand isn't expanded");
852 "Invalid type for expanded float");
858 std::pair<SDValue, SDValue> &Entry = ExpandedFloats[
Op];
859 assert(!Entry.first.getNode() &&
"Node already expanded");
866 std::pair<SDValue, SDValue> &Entry = SplitVectors[
Op];
867 RemapValue(Entry.first);
868 RemapValue(Entry.second);
869 assert(Entry.first.getNode() &&
"Operand isn't split");
881 "Invalid type for split vector");
887 std::pair<SDValue, SDValue> &Entry = SplitVectors[
Op];
888 assert(!Entry.first.getNode() &&
"Node already split");
893 void DAGTypeLegalizer::SetWidenedVector(
SDValue Op,
SDValue Result) {
896 "Invalid type for widened vector");
897 AnalyzeNewValue(Result);
917 SDValue DAGTypeLegalizer::BitConvertVectorToIntegerVector(
SDValue Op) {
947 bool DAGTypeLegalizer::CustomLowerNode(
SDNode *N,
EVT VT,
bool LegalizeResult) {
967 SetExpandedInteger(
SDValue(N, 0), Results[0], Results[1]);
969 ReplaceValueWith(
SDValue(N, 1), Results[2]);
975 "Custom lowering returned the wrong number of results!");
976 for (
unsigned i = 0, e = Results.
size(); i != e; ++
i) {
977 ReplaceValueWith(
SDValue(N, i), Results[i]);
985 bool DAGTypeLegalizer::CustomWidenLowerNode(
SDNode *N,
EVT VT) {
999 "Custom lowering returned the wrong number of results!");
1000 for (
unsigned i = 0, e = Results.
size(); i != e; ++
i)
1001 SetWidenedVector(
SDValue(N, i), Results[
i]);
1005 SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(
SDNode *N,
unsigned ResNo) {
1014 void DAGTypeLegalizer::GetPairElements(
SDValue Pair,
1050 }
else if (NumOps == 1) {
1054 }
else if (NumOps == 2) {
1060 for (
unsigned i = 0; i < NumOps; ++
i)
1068 std::pair<SDValue, SDValue>
1081 Entry.
isZExt = !isSigned;
1082 Args.push_back(Entry);
1090 CLI.setDebugLoc(
SDLoc(Node)).setChain(InChain)
1092 .setSExtResult(isSigned).setZExtResult(!isSigned);
1094 std::pair<SDValue, SDValue> CallInfo = TLI.
LowerCallTo(CLI);
1106 EVT BoolVT = getSetCCResultType(ValVT);
1109 return DAG.
getNode(ExtendCode, dl, BoolVT, Bool);
1122 "Unexpected types in WidenTargetBoolean");
1125 Bool = ModifyToType(Bool, WideVT, WithZeroes);
1126 return PromoteTargetBoolean(Bool, ValVT);
1130 void DAGTypeLegalizer::SplitInteger(
SDValue Op,
1145 void DAGTypeLegalizer::SplitInteger(
SDValue Op,
1149 SplitInteger(Op, HalfVT, HalfVT, Lo, Hi);
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
void push_back(const T &Elt)
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const
Get the CallingConv that should be used for the specified libcall.
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant, which is required to be operand #1) half of the integer or float value specified as operand #0.
LLVMContext * getContext() const
bool LegalizeTypes()
This transforms the SelectionDAG into a SelectionDAG that only uses types natively supported by the t...
Clients of various APIs that cause global effects on the DAG can optionally implement this interface...
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
static ISD::NodeType getExtendForContent(BooleanContent Content)
Function Alias Analysis Results
Type * getTypeForEVT(LLVMContext &Context) const
getTypeForEVT - This method returns an LLVM type corresponding to the specified EVT.
unsigned getNumOperands() const
Return the number of values used by this operation.
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned Num) const
This takes an arbitrary SelectionDAG as input and hacks on it until only value types the target machi...
void setNodeId(int Id)
Set unique node id.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
SDValue getExternalSymbol(const char *Sym, EVT VT)
bool isVector() const
isVector - Return true if this is a vector value type.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
This node's ID needs to be set to the number of its unprocessed operands.
Shift and rotation operations.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
EVT getScalarType() const
getScalarType - If this is a vector type, return the element type, otherwise return this...
void pop_back()
Remove the last element of the SetVector.
iterator_range< allnodes_iterator > allnodes()
LLVM_NODISCARD bool empty() const
EVT getVectorElementType() const
getVectorElementType - Given a vector type, return the type of each element.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
bool empty() const
Determine if the SetVector is empty or not.
const DataLayout & getDataLayout() const
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static cl::opt< bool > EnableExpensiveChecks("enable-legalize-types-checking", cl::Hidden)
SDNode * getNode() const
get the SDNode which holds the desired result
bool run()
This is the main entry point for the type legalizer.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
The instances of the Type class are immutable: once they are created, they are never changed...
This is a new node, not before seen, that was created in the process of legalizing some other node...
unsigned getScalarValueSizeInBits() const
void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
This class provides iterator support for SDUse operands that use a specific SDNode.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT - Extended Value Type.
std::vector< ArgListEntry > ArgListTy
This structure contains all information that is necessary for lowering calls.
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements)
getVectorVT - Returns the EVT that represents a vector NumElements in length, where each element is o...
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, bool isSigned, const SDLoc &dl, bool doesNotReturn=false, bool isReturnValueUsed=true) const
Returns a pair of (return value, chain).
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands...
SDValue CreateStackTemporary(EVT VT, unsigned minAlign=1)
Create a stack temporary, suitable for holding the specified value type.
virtual void ReplaceNodeResults(SDNode *, SmallVectorImpl< SDValue > &, SelectionDAG &) const
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
A SetVector that performs no allocations if smaller than a certain size.
void dump() const
Dump this node, for debugging.
void setNode(SDNode *N)
set the SDNode
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
This is a node that has already been processed.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
op_iterator op_begin() const
static use_iterator use_end()
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
const T & back() const
Return the last element of the SetVector.
int getNodeId() const
Return the unique node id.
EVT getValueType() const
Return the ValueType of the referenced return value.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
This class is used to form a handle around another node that is persistent and is updated across invo...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
All operands have been processed, so this node is ready to be handled.
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.Val alone...
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
TRUNCATE - Completely drop the high bits.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
getIntegerVT - Returns the EVT that represents an integer with the given number of bits...
virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
unsigned getVectorNumElements() const
getVectorNumElements - Given a vector type, return the number of elements it contains.