25 #define DEBUG_TYPE "legalize-types"
31 void DAGTypeLegalizer::PerformExpensiveChecks() {
82 for (
unsigned i = 0, e =
I->getNumValues(); i != e; ++i) {
87 if (ReplacedValues.find(Res) != ReplacedValues.end()) {
92 if (UI.getUse().getResNo() == i)
93 assert(UI->getNodeId() ==
NewNode &&
94 "Remapped value has non-trivial use!");
98 SDValue NewVal = ReplacedValues[Res];
100 while (I != ReplacedValues.end()) {
102 I = ReplacedValues.find(NewVal);
105 "ReplacedValues maps to a new node!");
107 if (PromotedIntegers.find(Res) != PromotedIntegers.end())
109 if (SoftenedFloats.find(Res) != SoftenedFloats.end())
111 if (ScalarizedVectors.find(Res) != ScalarizedVectors.end())
113 if (ExpandedIntegers.find(Res) != ExpandedIntegers.end())
115 if (ExpandedFloats.find(Res) != ExpandedFloats.end())
117 if (SplitVectors.find(Res) != SplitVectors.end())
119 if (WidenedVectors.find(Res) != WidenedVectors.end())
126 if ((I->getNodeId() ==
NewNode && Mapped > 1) ||
127 (I->getNodeId() !=
NewNode && Mapped != 0)) {
128 dbgs() <<
"Unprocessed value in a map!";
131 }
else if (isTypeLegal(Res.getValueType()) || IgnoreNodeResults(I)) {
133 dbgs() <<
"Value with legal type was transformed!";
138 dbgs() <<
"Processed value not in any map!";
140 }
else if (Mapped & (Mapped - 1)) {
141 dbgs() <<
"Value in multiple maps!";
148 dbgs() <<
" ReplacedValues";
150 dbgs() <<
" PromotedIntegers";
152 dbgs() <<
" SoftenedFloats";
154 dbgs() <<
" ScalarizedVectors";
156 dbgs() <<
" ExpandedIntegers";
158 dbgs() <<
" ExpandedFloats";
160 dbgs() <<
" SplitVectors";
162 dbgs() <<
" WidenedVectors";
170 for (
unsigned i = 0, e = NewNodes.
size(); i != e; ++i) {
174 assert(UI->getNodeId() ==
NewNode &&
"NewNode used by non-NewNode!");
182 bool Changed =
false;
199 if (I->getNumOperands() == 0) {
201 Worklist.push_back(I);
208 while (!Worklist.empty()) {
212 PerformExpensiveChecks();
214 SDNode *N = Worklist.back();
217 "Node should be ready if on worklist!");
219 if (IgnoreNodeResults(N))
224 for (
unsigned i = 0, NumResults = N->
getNumValues(); i < NumResults; ++i) {
226 switch (getTypeAction(ResultVT)) {
235 PromoteIntegerResult(N, i);
239 ExpandIntegerResult(N, i);
243 SoftenFloatResult(N, i);
247 ExpandFloatResult(N, i);
251 ScalarizeVectorResult(N, i);
255 SplitVectorResult(N, i);
259 WidenVectorResult(N, i);
263 PromoteFloatResult(N, i);
274 bool NeedsReanalyzing =
false;
276 for (i = 0; i != NumOperands; ++i) {
281 switch (getTypeAction(OpVT)) {
288 NeedsReanalyzing = PromoteIntegerOperand(N, i);
292 NeedsReanalyzing = ExpandIntegerOperand(N, i);
296 NeedsReanalyzing = SoftenFloatOperand(N, i);
300 NeedsReanalyzing = ExpandFloatOperand(N, i);
304 NeedsReanalyzing = ScalarizeVectorOperand(N, i);
308 NeedsReanalyzing = SplitVectorOperand(N, i);
312 NeedsReanalyzing = WidenVectorOperand(N, i);
316 NeedsReanalyzing = PromoteFloatOperand(N, i);
326 if (NeedsReanalyzing) {
331 SDNode *M = AnalyzeNewNode(N);
339 "Node morphing changed the number of results!");
340 for (
unsigned i = 0, e = N->
getNumValues(); i != e; ++i)
350 if (i == NumOperands) {
373 Worklist.push_back(User);
386 assert(NodeId ==
Unanalyzed &&
"Unknown node ID!");
391 Worklist.push_back(User);
398 PerformExpensiveChecks();
417 if (!IgnoreNodeResults(I))
418 for (
unsigned i = 0, NumVals = I->getNumValues(); i < NumVals; ++i)
419 if (!isTypeLegal(I->getValueType(i))) {
420 dbgs() <<
"Result type " << i <<
" illegal!\n";
425 for (
unsigned i = 0, NumOps = I->getNumOperands(); i < NumOps; ++i)
426 if (!IgnoreNodeResults(I->getOperand(i).getNode()) &&
427 !isTypeLegal(I->getOperand(i).getValueType())) {
428 dbgs() <<
"Operand type " << i <<
" illegal!\n";
434 dbgs() <<
"New node not analyzed?\n";
436 dbgs() <<
"Unanalyzed node not noticed?\n";
437 else if (I->getNodeId() > 0)
438 dbgs() <<
"Operand not processed?\n";
440 dbgs() <<
"Not added to worklist?\n";
445 I->dump(&DAG);
dbgs() <<
"\n";
479 unsigned NumProcessed = 0;
489 if (!NewOps.
empty()) {
492 }
else if (Op != OrigOp) {
500 if (!NewOps.
empty()) {
524 Worklist.push_back(N);
531 void DAGTypeLegalizer::AnalyzeNewValue(
SDValue &Val) {
551 void DAGTypeLegalizer::ExpungeNode(
SDNode *N) {
558 if (ReplacedValues.find(
SDValue(N, i)) != ReplacedValues.end())
567 E = PromotedIntegers.end(); I != E; ++
I) {
568 assert(I->first.getNode() !=
N);
569 RemapValue(I->second);
573 E = SoftenedFloats.end(); I != E; ++
I) {
574 assert(I->first.getNode() !=
N);
575 RemapValue(I->second);
579 E = ScalarizedVectors.end(); I != E; ++
I) {
580 assert(I->first.getNode() !=
N);
581 RemapValue(I->second);
585 E = WidenedVectors.end(); I != E; ++
I) {
586 assert(I->first.getNode() !=
N);
587 RemapValue(I->second);
591 I = ExpandedIntegers.begin(), E = ExpandedIntegers.end(); I != E; ++
I){
592 assert(I->first.getNode() !=
N);
593 RemapValue(I->second.first);
594 RemapValue(I->second.second);
598 I = ExpandedFloats.begin(), E = ExpandedFloats.end(); I != E; ++
I) {
599 assert(I->first.getNode() !=
N);
600 RemapValue(I->second.first);
601 RemapValue(I->second.second);
605 I = SplitVectors.begin(), E = SplitVectors.end(); I != E; ++
I) {
606 assert(I->first.getNode() !=
N);
607 RemapValue(I->second.first);
608 RemapValue(I->second.second);
612 E = ReplacedValues.end(); I != E; ++
I)
613 RemapValue(I->second);
615 for (
unsigned i = 0, e = N->
getNumValues(); i != e; ++i)
616 ReplacedValues.erase(
SDValue(N, i));
621 void DAGTypeLegalizer::RemapValue(
SDValue &N) {
623 if (I != ReplacedValues.end()) {
626 RemapValue(I->second);
645 DTL(dtl), NodesToAnalyze(nta) {}
650 "Invalid node ID for RAUW deletion!");
653 assert(E &&
"Node not replaced?");
654 DTL.NoteDeletion(N, E);
658 NodesToAnalyze.remove(N);
665 NodesToAnalyze.insert(E);
668 void NodeUpdated(
SDNode *N)
override {
674 "Invalid node ID for RAUW deletion!");
676 NodesToAnalyze.insert(N);
685 void DAGTypeLegalizer::ReplaceValueWith(
SDValue From,
SDValue To) {
686 assert(From.
getNode() != To.
getNode() &&
"Potential legalization loop!");
695 NodeUpdateListener NUL(*
this, NodesToAnalyze);
701 ReplacedValues[From] = To;
704 while (!NodesToAnalyze.
empty()) {
714 SDNode *M = AnalyzeNewNode(N);
720 "Node morphing changed the number of results!");
721 for (
unsigned i = 0, e = N->
getNumValues(); i != e; ++i) {
731 ReplacedValues[OldVal] = NewVal;
742 void DAGTypeLegalizer::SetPromotedInteger(
SDValue Op,
SDValue Result) {
745 "Invalid type for promoted integer");
746 AnalyzeNewValue(Result);
748 SDValue &OpEntry = PromotedIntegers[Op];
749 assert(!OpEntry.
getNode() &&
"Node is already promoted!");
753 void DAGTypeLegalizer::SetSoftenedFloat(
SDValue Op,
SDValue Result) {
756 "Invalid type for softened float");
757 AnalyzeNewValue(Result);
759 SDValue &OpEntry = SoftenedFloats[Op];
760 assert(!OpEntry.
getNode() &&
"Node is already converted to integer!");
764 void DAGTypeLegalizer::SetPromotedFloat(
SDValue Op,
SDValue Result) {
767 "Invalid type for promoted float");
768 AnalyzeNewValue(Result);
770 SDValue &OpEntry = PromotedFloats[Op];
771 assert(!OpEntry.
getNode() &&
"Node is already promoted!");
775 void DAGTypeLegalizer::SetScalarizedVector(
SDValue Op,
SDValue Result) {
781 "Invalid type for scalarized vector");
782 AnalyzeNewValue(Result);
784 SDValue &OpEntry = ScalarizedVectors[Op];
785 assert(!OpEntry.
getNode() &&
"Node is already scalarized!");
791 std::pair<SDValue, SDValue> &Entry = ExpandedIntegers[Op];
792 RemapValue(Entry.first);
793 RemapValue(Entry.second);
794 assert(Entry.first.getNode() &&
"Operand isn't expanded");
804 "Invalid type for expanded integer");
810 std::pair<SDValue, SDValue> &Entry = ExpandedIntegers[Op];
811 assert(!Entry.first.getNode() &&
"Node already expanded");
818 std::pair<SDValue, SDValue> &Entry = ExpandedFloats[Op];
819 RemapValue(Entry.first);
820 RemapValue(Entry.second);
821 assert(Entry.first.getNode() &&
"Operand isn't expanded");
831 "Invalid type for expanded float");
837 std::pair<SDValue, SDValue> &Entry = ExpandedFloats[Op];
838 assert(!Entry.first.getNode() &&
"Node already expanded");
845 std::pair<SDValue, SDValue> &Entry = SplitVectors[Op];
846 RemapValue(Entry.first);
847 RemapValue(Entry.second);
848 assert(Entry.first.getNode() &&
"Operand isn't split");
860 "Invalid type for split vector");
866 std::pair<SDValue, SDValue> &Entry = SplitVectors[Op];
867 assert(!Entry.first.getNode() &&
"Node already split");
872 void DAGTypeLegalizer::SetWidenedVector(
SDValue Op,
SDValue Result) {
875 "Invalid type for widened vector");
876 AnalyzeNewValue(Result);
878 SDValue &OpEntry = WidenedVectors[Op];
879 assert(!OpEntry.
getNode() &&
"Node already widened!");
897 SDValue DAGTypeLegalizer::BitConvertVectorToIntegerVector(
SDValue Op) {
917 false,
false,
false, 0);
928 bool DAGTypeLegalizer::CustomLowerNode(
SDNode *N,
EVT VT,
bool LegalizeResult) {
948 SetExpandedInteger(
SDValue(N, 0), Results[0], Results[1]);
950 ReplaceValueWith(
SDValue(N, 1), Results[2]);
956 "Custom lowering returned the wrong number of results!");
957 for (
unsigned i = 0, e = Results.
size(); i != e; ++i) {
958 ReplaceValueWith(
SDValue(N, i), Results[i]);
966 bool DAGTypeLegalizer::CustomWidenLowerNode(
SDNode *N,
EVT VT) {
980 "Custom lowering returned the wrong number of results!");
981 for (
unsigned i = 0, e = Results.
size(); i != e; ++i)
982 SetWidenedVector(
SDValue(N, i), Results[i]);
986 SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(
SDNode *N,
unsigned ResNo) {
987 for (
unsigned i = 0, e = N->
getNumValues(); i != e; ++i)
995 void DAGTypeLegalizer::GetPairElements(
SDValue Pair,
1045 }
else if (NumOps == 1) {
1049 }
else if (NumOps == 2) {
1055 for (
unsigned i = 0; i < NumOps; ++i)
1059 &Ops[0], NumOps, isSigned, dl).first;
1064 std::pair<SDValue, SDValue>
1078 Entry.
isZExt = !isSigned;
1079 Args.push_back(Entry);
1087 CLI.setDebugLoc(
SDLoc(Node)).setChain(InChain)
1089 .setSExtResult(isSigned).setZExtResult(!isSigned);
1091 std::pair<SDValue, SDValue> CallInfo = TLI.
LowerCallTo(CLI);
1103 EVT BoolVT = getSetCCResultType(ValVT);
1106 return DAG.
getNode(ExtendCode, dl, BoolVT, Bool);
1111 void DAGTypeLegalizer::SplitInteger(
SDValue Op,
1126 void DAGTypeLegalizer::SplitInteger(
SDValue Op,
1130 SplitInteger(Op, HalfVT, HalfVT, Lo, Hi);
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...
void dump() const
Dump this node, for debugging.
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)
Type * getTypeForEVT(LLVMContext &Context) const
getTypeForEVT - This method returns an LLVM type corresponding to the specified EVT.
SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, bool isInvariant, unsigned Alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands...
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
DAGTypeLegalizer - This takes an arbitrary SelectionDAG as input and hacks on it until only value typ...
void setNodeId(int Id)
Set unique node id.
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 getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, unsigned Alignment, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
Unanalyzed - This node's ID needs to be set to the number of its unprocessed operands.
Shift and rotation operations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, SDLoc dl, bool doesNotReturn=false, bool isReturnValueUsed=true) const
Returns a pair of (return value, chain).
allnodes_const_iterator allnodes_end() const
void pop_back()
Remove the last element of the SetVector.
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 LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Simple integer binary arithmetic operators.
bool empty() const
Determine if the SetVector is empty or not.
const DataLayout & getDataLayout() const
static cl::opt< bool > EnableExpensiveChecks("enable-legalize-types-checking", cl::Hidden)
SDNode * getNode() const
get the SDNode which holds the desired result
bool run()
run - This is the main entry point for the type legalizer.
The instances of the Type class are immutable: once they are created, they are never changed...
NewNode - This is a new node, not before seen, that was created in the process of legalizing some oth...
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.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
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...
MachinePointerInfo - This class contains a discriminated union of information about pointers in memor...
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
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.
allnodes_const_iterator allnodes_begin() const
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.
Processed - 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.
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
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.
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, SDLoc DL, EVT VT, bool isTarget=false, bool isOpaque=false)
This class is used to form a handle around another node that is persistent and is updated across invo...
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...
SDValue getZExtOrTrunc(SDValue Op, SDLoc DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
ReadyToProcess - 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...
SDValue getIntPtrConstant(uint64_t Val, SDLoc DL, bool isTarget=false)
unsigned getVectorNumElements() const
getVectorNumElements - Given a vector type, return the number of elements it contains.