Changeset View
Changeset View
Standalone View
Standalone View
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Show First 20 Lines • Show All 919 Lines • ▼ Show 20 Lines | public: | ||||
/// | /// | ||||
void NodeDeleted(SDNode *N, SDNode *E) override { | void NodeDeleted(SDNode *N, SDNode *E) override { | ||||
if (ISelPosition == SelectionDAG::allnodes_iterator(N)) | if (ISelPosition == SelectionDAG::allnodes_iterator(N)) | ||||
++ISelPosition; | ++ISelPosition; | ||||
} | } | ||||
}; | }; | ||||
} // end anonymous namespace | } // end anonymous namespace | ||||
static bool isStrictFPOp(SDNode *Node) { | |||||
unsigned Opc = Node->getOpcode(); | |||||
if (Opc == ISD::STRICT_FADD || Opc == ISD::STRICT_FSUB || | |||||
Opc == ISD::STRICT_FMUL || Opc == ISD::STRICT_FDIV || | |||||
Opc == ISD::STRICT_FREM) | |||||
return true; | |||||
return false; | |||||
} | |||||
arsenm: You can replace this with a switch strict->regular op mapping, and then you avoid having to… | |||||
SDNode* SelectionDAGISel::MutateStrictFPToFP(SDNode *Node) { | |||||
unsigned OrigOpc = Node->getOpcode(); | |||||
unsigned NewOpc; | |||||
switch (OrigOpc) { | |||||
default: llvm_unreachable("Unexpected opcode for strict FP node!"); | |||||
case ISD::STRICT_FADD: NewOpc = ISD::FADD; break; | |||||
case ISD::STRICT_FSUB: NewOpc = ISD::FSUB; break; | |||||
case ISD::STRICT_FMUL: NewOpc = ISD::FMUL; break; | |||||
case ISD::STRICT_FDIV: NewOpc = ISD::FDIV; break; | |||||
case ISD::STRICT_FREM: NewOpc = ISD::FREM; break; | |||||
} | |||||
// We're taking this node out of the chain, so we need to re-link things. | |||||
SDValue InputChain = Node->getOperand(0); | |||||
SDValue OutputChain = SDValue(Node, 1); | |||||
CurDAG->ReplaceAllUsesOfValueWith(OutputChain, InputChain); | |||||
SDVTList VTs = CurDAG->getVTList(Node->getOperand(1).getValueType()); | |||||
SDValue Ops[2] = { Node->getOperand(1), Node->getOperand(2) }; | |||||
Not Done ReplyInline ActionsThis doesn't need to be a SmallVector. You can just use SDValue Ops[2] = { Node->getOperand(1), Node->getOperand(2) }; craig.topper: This doesn't need to be a SmallVector. You can just use
SDValue Ops[2] = { Node->getOperand… | |||||
SDNode *Res = CurDAG->MorphNodeTo(Node, NewOpc, VTs, Ops); | |||||
// MorphNodeTo can operate in two ways: if an existing node with the | |||||
// specified operands exists, it can just return it. Otherwise, it | |||||
// updates the node in place to have the requested operands. | |||||
if (Res == Node) { | |||||
// If we updated the node in place, reset the node ID. To the isel, | |||||
// this should be just like a newly allocated machine node. | |||||
Res->setNodeId(-1); | |||||
} else { | |||||
CurDAG->ReplaceAllUsesWith(Node, Res); | |||||
CurDAG->RemoveDeadNode(Node); | |||||
} | |||||
return Res; | |||||
} | |||||
void SelectionDAGISel::DoInstructionSelection() { | void SelectionDAGISel::DoInstructionSelection() { | ||||
DEBUG(dbgs() << "===== Instruction selection begins: BB#" | DEBUG(dbgs() << "===== Instruction selection begins: BB#" | ||||
<< FuncInfo->MBB->getNumber() | << FuncInfo->MBB->getNumber() | ||||
<< " '" << FuncInfo->MBB->getName() << "'\n"); | << " '" << FuncInfo->MBB->getName() << "'\n"); | ||||
PreprocessISelDAG(); | PreprocessISelDAG(); | ||||
// Select target instructions for the DAG. | // Select target instructions for the DAG. | ||||
Show All 19 Lines | // Select target instructions for the DAG. | ||||
while (ISelPosition != CurDAG->allnodes_begin()) { | while (ISelPosition != CurDAG->allnodes_begin()) { | ||||
SDNode *Node = &*--ISelPosition; | SDNode *Node = &*--ISelPosition; | ||||
// Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes, | // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes, | ||||
// but there are currently some corner cases that it misses. Also, this | // but there are currently some corner cases that it misses. Also, this | ||||
// makes it theoretically possible to disable the DAGCombiner. | // makes it theoretically possible to disable the DAGCombiner. | ||||
if (Node->use_empty()) | if (Node->use_empty()) | ||||
continue; | continue; | ||||
// When we are using non-default rounding modes or FP exception behavior | |||||
// FP operations are represented by StrictFP pseudo-operations. They | |||||
// need to be simplified here so that the target-specific instruction | |||||
// selectors know how to handle them. | |||||
bool IsStrictFPOp = isStrictFPOp(Node); | |||||
if (IsStrictFPOp) | |||||
Node = MutateStrictFPToFP(Node); | |||||
Select(Node); | Select(Node); | ||||
// FIXME: Add code here to attach an implicit def and use of | |||||
// target-specific FP environment registers. | |||||
} | } | ||||
CurDAG->setRoot(Dummy.getValue()); | CurDAG->setRoot(Dummy.getValue()); | ||||
} | } | ||||
DEBUG(dbgs() << "===== Instruction selection ends:\n"); | DEBUG(dbgs() << "===== Instruction selection ends:\n"); | ||||
PostprocessISelDAG(); | PostprocessISelDAG(); | ||||
▲ Show 20 Lines • Show All 2,698 Lines • Show Last 20 Lines |
You can replace this with a switch strict->regular op mapping, and then you avoid having to switch over these again in MutateStrictFPToFP