aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp59
1 files changed, 44 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index dfda7d8b9f81..19a52fde44c1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -17,7 +17,10 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/GCMetadata.h"
@@ -27,6 +30,7 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetOpcodes.h"
@@ -168,7 +172,7 @@ static Optional<int> findPreviousSpillSlot(const Value *Val,
const auto &RelocationMap =
Builder.FuncInfo.StatepointRelocationMaps[Relocate->getStatepoint()];
- auto It = RelocationMap.find(Relocate->getDerivedPtr());
+ auto It = RelocationMap.find(Relocate);
if (It == RelocationMap.end())
return None;
@@ -192,10 +196,10 @@ static Optional<int> findPreviousSpillSlot(const Value *Val,
for (auto &IncomingValue : Phi->incoming_values()) {
Optional<int> SpillSlot =
findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth - 1);
- if (!SpillSlot.hasValue())
+ if (!SpillSlot)
return None;
- if (MergedResult.hasValue() && *MergedResult != *SpillSlot)
+ if (MergedResult && *MergedResult != *SpillSlot)
return None;
MergedResult = SpillSlot;
@@ -276,7 +280,7 @@ static void reservePreviousStackSlotForValue(const Value *IncomingValue,
const int LookUpDepth = 6;
Optional<int> Index =
findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth);
- if (!Index.hasValue())
+ if (!Index)
return;
const auto &StatepointSlots = Builder.FuncInfo.StatepointStackSlots;
@@ -526,14 +530,14 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
GCStrategy &S = GFI->getStrategy();
for (const Value *V : SI.Bases) {
auto Opt = S.isGCManagedPointer(V->getType()->getScalarType());
- if (Opt.hasValue()) {
+ if (Opt) {
assert(Opt.getValue() &&
"non gc managed base pointer found in statepoint");
}
}
for (const Value *V : SI.Ptrs) {
auto Opt = S.isGCManagedPointer(V->getType()->getScalarType());
- if (Opt.hasValue()) {
+ if (Opt) {
assert(Opt.getValue() &&
"non gc managed derived pointer found in statepoint");
}
@@ -880,8 +884,9 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops);
DAG.setNodeMemRefs(StatepointMCNode, MemRefs);
- // For values lowered to tied-defs, create the virtual registers. Note that
- // for simplicity, we *always* create a vreg even within a single block.
+ // For values lowered to tied-defs, create the virtual registers if used
+ // in other blocks. For local gc.relocate record appropriate statepoint
+ // result in StatepointLoweringState.
DenseMap<SDValue, Register> VirtRegs;
for (const auto *Relocate : SI.GCRelocates) {
Value *Derived = Relocate->getDerivedPtr();
@@ -889,12 +894,23 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
if (!LowerAsVReg.count(SD))
continue;
+ SDValue Relocated = SDValue(StatepointMCNode, LowerAsVReg[SD]);
+
+ // Handle local relocate. Note that different relocates might
+ // map to the same SDValue.
+ if (SI.StatepointInstr->getParent() == Relocate->getParent()) {
+ SDValue Res = StatepointLowering.getLocation(SD);
+ if (Res)
+ assert(Res == Relocated);
+ else
+ StatepointLowering.setLocation(SD, Relocated);
+ continue;
+ }
+
// Handle multiple gc.relocates of the same input efficiently.
if (VirtRegs.count(SD))
continue;
- SDValue Relocated = SDValue(StatepointMCNode, LowerAsVReg[SD]);
-
auto *RetTy = Relocate->getType();
Register Reg = FuncInfo.CreateRegs(RetTy);
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
@@ -915,8 +931,13 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
SDValue SDV = getValue(V);
SDValue Loc = StatepointLowering.getLocation(SDV);
+ bool IsLocal = (Relocate->getParent() == StatepointInstr->getParent());
+
RecordType Record;
- if (LowerAsVReg.count(SDV)) {
+ if (IsLocal && LowerAsVReg.count(SDV)) {
+ // Result is already stored in StatepointLowering
+ Record.type = RecordType::SDValueNode;
+ } else if (LowerAsVReg.count(SDV)) {
Record.type = RecordType::VReg;
assert(VirtRegs.count(SDV));
Record.payload.Reg = VirtRegs[SDV];
@@ -932,7 +953,7 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
if (Relocate->getParent() != StatepointInstr->getParent())
ExportFromCurrentBlock(V);
}
- RelocationMap[V] = Record;
+ RelocationMap[Relocate] = Record;
}
@@ -1148,8 +1169,8 @@ void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl(
unsigned DefaultID = StatepointDirectives::DeoptBundleStatepointID;
auto SD = parseStatepointDirectivesFromAttrs(Call->getAttributes());
- SI.ID = SD.StatepointID.getValueOr(DefaultID);
- SI.NumPatchBytes = SD.NumPatchBytes.getValueOr(0);
+ SI.ID = SD.StatepointID.value_or(DefaultID);
+ SI.NumPatchBytes = SD.NumPatchBytes.value_or(0);
SI.DeoptState =
ArrayRef<const Use>(DeoptBundle.Inputs.begin(), DeoptBundle.Inputs.end());
@@ -1210,11 +1231,19 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
const Value *DerivedPtr = Relocate.getDerivedPtr();
auto &RelocationMap =
FuncInfo.StatepointRelocationMaps[Relocate.getStatepoint()];
- auto SlotIt = RelocationMap.find(DerivedPtr);
+ auto SlotIt = RelocationMap.find(&Relocate);
assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value");
const RecordType &Record = SlotIt->second;
// If relocation was done via virtual register..
+ if (Record.type == RecordType::SDValueNode) {
+ assert(Relocate.getStatepoint()->getParent() == Relocate.getParent() &&
+ "Nonlocal gc.relocate mapped via SDValue");
+ SDValue SDV = StatepointLowering.getLocation(getValue(DerivedPtr));
+ assert(SDV.getNode() && "empty SDValue");
+ setValue(&Relocate, SDV);
+ return;
+ }
if (Record.type == RecordType::VReg) {
Register InReg = Record.payload.Reg;
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),