mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[RISCV][NFCI] Handle redundant splitf64+buildpairf64 pairs during instruction selection
Although we can't write a tablegen pattern to remove redundant splitf64+buildf64 pairs due to the multiple return values, we can handle it with some C++ selection code. This is simpler than removing them after instruction selection through RISCVDAGToDAGISel::PostprocessISelDAG, as was done previously. llvm-svn: 343712
This commit is contained in:
parent
e1e91bce0e
commit
b0dadbdba9
@ -56,13 +56,11 @@ public:
|
||||
|
||||
private:
|
||||
void doPeepholeLoadStoreADDI();
|
||||
void doPeepholeBuildPairF64SplitF64();
|
||||
};
|
||||
}
|
||||
|
||||
void RISCVDAGToDAGISel::PostprocessISelDAG() {
|
||||
doPeepholeLoadStoreADDI();
|
||||
doPeepholeBuildPairF64SplitF64();
|
||||
}
|
||||
|
||||
void RISCVDAGToDAGISel::Select(SDNode *Node) {
|
||||
@ -98,6 +96,18 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
|
||||
ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
|
||||
return;
|
||||
}
|
||||
case RISCVISD::SplitF64: {
|
||||
// If the input to SplitF64 is just BuildPairF64 then the operation is
|
||||
// redundant. Instead, use BuildPairF64's operands directly. This pattern
|
||||
// can't be written in tablegen due to the multiple outputs.
|
||||
SDValue Op0 = Node->getOperand(0);
|
||||
if (Op0->getOpcode() != RISCVISD::BuildPairF64)
|
||||
break;
|
||||
ReplaceUses(SDValue(Node, 0), Op0.getOperand(0));
|
||||
ReplaceUses(SDValue(Node, 1), Op0.getOperand(1));
|
||||
CurDAG->RemoveDeadNode(Node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Select the default instruction.
|
||||
@ -216,43 +226,6 @@ void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
|
||||
}
|
||||
}
|
||||
|
||||
// Remove redundant BuildPairF64+SplitF64 pairs. i.e. cases where an f64 is
|
||||
// built of two i32 values, only to be split apart again. This must be done
|
||||
// here as a peephole optimisation as the DAG has not been fully legalized at
|
||||
// the point BuildPairF64/SplitF64 nodes are created in RISCVISelLowering, so
|
||||
// some nodes would not yet have been replaced with libcalls.
|
||||
void RISCVDAGToDAGISel::doPeepholeBuildPairF64SplitF64() {
|
||||
SelectionDAG::allnodes_iterator Position(CurDAG->getRoot().getNode());
|
||||
++Position;
|
||||
|
||||
while (Position != CurDAG->allnodes_begin()) {
|
||||
SDNode *N = &*--Position;
|
||||
// Skip dead nodes and any nodes other than SplitF64Pseudo.
|
||||
if (N->use_empty() || !N->isMachineOpcode() ||
|
||||
!(N->getMachineOpcode() == RISCV::SplitF64Pseudo))
|
||||
continue;
|
||||
|
||||
// If the operand to SplitF64 is a BuildPairF64, the split operation is
|
||||
// redundant. Just use the operands to BuildPairF64 as the result.
|
||||
SDValue F64Val = N->getOperand(0);
|
||||
if (F64Val.isMachineOpcode() &&
|
||||
F64Val.getMachineOpcode() == RISCV::BuildPairF64Pseudo) {
|
||||
LLVM_DEBUG(
|
||||
dbgs() << "Removing redundant SplitF64Pseudo and replacing uses "
|
||||
"with BuildPairF64Pseudo operands:\n");
|
||||
LLVM_DEBUG(dbgs() << "N: ");
|
||||
LLVM_DEBUG(N->dump(CurDAG));
|
||||
LLVM_DEBUG(dbgs() << "F64Val: ");
|
||||
LLVM_DEBUG(F64Val->dump(CurDAG));
|
||||
LLVM_DEBUG(dbgs() << "\n");
|
||||
SDValue From[] = {SDValue(N, 0), SDValue(N, 1)};
|
||||
SDValue To[] = {F64Val.getOperand(0), F64Val.getOperand(1)};
|
||||
CurDAG->ReplaceAllUsesOfValuesWith(From, To, 2);
|
||||
}
|
||||
}
|
||||
CurDAG->RemoveDeadNodes();
|
||||
}
|
||||
|
||||
// This pass converts a legalized DAG into a RISCV-specific DAG, ready
|
||||
// for instruction scheduling.
|
||||
FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) {
|
||||
|
Loading…
Reference in New Issue
Block a user