aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
diff options
context:
space:
mode:
authorDenis Antrushin <dantrushin@azul.com>2022-04-10 15:31:31 +0700
committerDenis Antrushin <dantrushin@gmail.com>2022-05-30 19:07:30 +0300
commit85322e82be5014fb0abddb3a36df928d16760fba (patch)
tree3561261fd969d8e3c91579d75a78b00ac3df3da4 /llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
parente576280380d3f5221cfcc14e9fabeacc8506a43c (diff)
downloadllvm-85322e82be5014fb0abddb3a36df928d16760fba.zip
llvm-85322e82be5014fb0abddb3a36df928d16760fba.tar.gz
llvm-85322e82be5014fb0abddb3a36df928d16760fba.tar.bz2
[TwoAddressInstructionPass] Special processing of STATEPOINT instruction.
STATEPOINT is a special pseudo instruction which represent Moving GC semantic to LLVM. Every tied def/use VReg pair in STATEPOINT represent same physical register which can 'magically' change during call wrapped by statepoint. (By construction, tied use operand is not live across STATEPOINT). This means that when converting into two-address form, there is not need to insert COPY instruction before stateppoint, what TwoAddressInstruction pass does for 'regular' instructions. Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D124631
Diffstat (limited to 'llvm/lib/CodeGen/TwoAddressInstructionPass.cpp')
-rw-r--r--llvm/lib/CodeGen/TwoAddressInstructionPass.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index bebb35e..0ba2aba 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -161,6 +161,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
bool collectTiedOperands(MachineInstr *MI, TiedOperandMap&);
void processTiedPairs(MachineInstr *MI, TiedPairList&, unsigned &Dist);
void eliminateRegSequence(MachineBasicBlock::iterator&);
+ void processStatepoint(MachineInstr *MI, TiedOperandMap &TiedOperands);
public:
static char ID; // Pass identification, replacement for typeid
@@ -1627,6 +1628,56 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
}
}
+// For every tied operand pair this function transforms statepoint from
+// RegA = STATEPOINT ... RegB(tied-def N)
+// to
+// RegB = STATEPOINT ... RegB(tied-def N)
+// and replaces all uses of RegA with RegB.
+// No extra COPY instruction is necessary because tied use is killed at
+// STATEPOINT.
+void TwoAddressInstructionPass::processStatepoint(
+ MachineInstr *MI, TiedOperandMap &TiedOperands) {
+
+ for (auto &TO : TiedOperands) {
+ Register RegB = TO.first;
+ assert(TO.second.size() == 1 && "statepoints has single tied use");
+
+ unsigned SrcIdx = TO.second[0].first;
+ unsigned DstIdx = TO.second[0].second;
+
+ MachineOperand &DstMO = MI->getOperand(DstIdx);
+ Register RegA = DstMO.getReg();
+
+ assert(RegB == MI->getOperand(SrcIdx).getReg());
+
+ if (RegA == RegB)
+ continue;
+
+ MRI->replaceRegWith(RegA, RegB);
+
+ if (LIS) {
+ VNInfo::Allocator &A = LIS->getVNInfoAllocator();
+ LiveInterval &LI = LIS->getInterval(RegB);
+ for (auto &S : LIS->getInterval(RegA)) {
+ VNInfo *VNI = LI.getNextValue(S.start, A);
+ LiveRange::Segment NewSeg(S.start, S.end, VNI);
+ LI.addSegment(NewSeg);
+ }
+ LIS->removeInterval(RegA);
+ }
+
+ if (LV) {
+ if (MI->getOperand(SrcIdx).isKill())
+ LV->removeVirtualRegisterKilled(RegB, *MI);
+ LiveVariables::VarInfo &SrcInfo = LV->getVarInfo(RegB);
+ LiveVariables::VarInfo &DstInfo = LV->getVarInfo(RegA);
+ SrcInfo.AliveBlocks |= DstInfo.AliveBlocks;
+ for (auto *KillMI : DstInfo.Kills)
+ LV->addVirtualRegisterKilled(RegB, *KillMI, false);
+ }
+ }
+}
+
/// Reduce two-address instructions to two operands.
bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
MF = &Func;
@@ -1720,6 +1771,14 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
}
}
+ if (mi->getOpcode() == TargetOpcode::STATEPOINT) {
+ processStatepoint(&*mi, TiedOperands);
+ TiedOperands.clear();
+ LLVM_DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);
+ mi = nmi;
+ continue;
+ }
+
// Now iterate over the information collected above.
for (auto &TO : TiedOperands) {
processTiedPairs(&*mi, TO.second, Dist);