forked from OSchip/llvm-project
llvm-reduce: Handle cloning MachineFrameInfo and stack objects
This didn't work at all before, and would assert on any frame index. Also copy the other fields, which I believe should cover everything. There are a few that are untested since MIR serialization is apparently still missing them (isStatepointSpillSlot, ObjectSSPLayout, and ObjectSExt/ObjectZExt).
This commit is contained in:
parent
2503f28648
commit
f163106f39
|
@ -359,6 +359,7 @@ public:
|
||||||
/// This object is used for SjLj exceptions.
|
/// This object is used for SjLj exceptions.
|
||||||
int getFunctionContextIndex() const { return FunctionContextIdx; }
|
int getFunctionContextIndex() const { return FunctionContextIdx; }
|
||||||
void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
|
void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
|
||||||
|
bool hasFunctionContextIndex() const { return FunctionContextIdx != -1; }
|
||||||
|
|
||||||
/// This method may be called any time after instruction
|
/// This method may be called any time after instruction
|
||||||
/// selection is complete to determine if there is a call to
|
/// selection is complete to determine if there is a call to
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
# REQUIRES: amdgpu-registered-target
|
||||||
|
# RUN: llvm-reduce -simplify-mir -mtriple=amdgcn-amd-amdhsa --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2> %t.log
|
||||||
|
# RUN: FileCheck --match-full-lines --check-prefix=RESULT %s < %t
|
||||||
|
|
||||||
|
# CHECK-INTERESTINGNESS-COUNT-15: V_MOV_B32
|
||||||
|
|
||||||
|
# RESULT: frameInfo:
|
||||||
|
# RESULT-NEXT: isFrameAddressTaken: true
|
||||||
|
# RESULT-NEXT: isReturnAddressTaken: true
|
||||||
|
# RESULT-NEXT: hasStackMap: true
|
||||||
|
# RESULT-NEXT: hasPatchPoint: true
|
||||||
|
# RESULT-NEXT: offsetAdjustment: 128
|
||||||
|
# RESULT-NEXT: maxAlignment: 64
|
||||||
|
# RESULT-NEXT: adjustsStack: true
|
||||||
|
# RESULT-NEXT: hasCalls: true
|
||||||
|
# RESULT-NEXT: stackProtector: '%stack.9.guard'
|
||||||
|
# RESULT-NEXT: maxCallFrameSize: 420
|
||||||
|
# RESULT-NEXT: cvBytesOfCalleeSavedRegisters: 48
|
||||||
|
# RESULT-NEXT: hasOpaqueSPAdjustment: true
|
||||||
|
# RESULT-NEXT: hasVAStart: true
|
||||||
|
# RESULT-NEXT: hasMustTailInVarArgFunc: true
|
||||||
|
# RESULT-NEXT: hasTailCall: true
|
||||||
|
# RESULT-NEXT: savePoint: '%bb.1'
|
||||||
|
# RESULT-NEXT: restorePoint: '%bb.2'
|
||||||
|
|
||||||
|
# RESULT-NEXT: fixedStack:
|
||||||
|
# RESULT-NEXT: - { id: 0, offset: 56, size: 4, alignment: 8, callee-saved-register: '$sgpr44',
|
||||||
|
# RESULT-NEXT: callee-saved-restored: false }
|
||||||
|
# RESULT-NEXT: - { id: 1, offset: 52, size: 4, alignment: 4, callee-saved-register: '$sgpr43' }
|
||||||
|
# RESULT-NEXT: - { id: 2, offset: 48, size: 8, alignment: 16, isAliased: true }
|
||||||
|
# RESULT-NEXT: - { id: 3, offset: 16, size: 16, alignment: 16 }
|
||||||
|
# RESULT-NEXT: - { id: 4, size: 8, alignment: 16 }
|
||||||
|
|
||||||
|
# RESULT-NEXT: stack:
|
||||||
|
# RESULT-NEXT: - { id: 0, name: bigalloca, offset: 16, size: 16, alignment: 8 }
|
||||||
|
# RESULT-NEXT: - { id: 1, offset: 64, size: 4, alignment: 16, debug-info-variable: '!8',
|
||||||
|
# RESULT-NEXT: debug-info-expression: '!DIExpression()', debug-info-location: '!10' }
|
||||||
|
# RESULT-NEXT: - { id: 2, type: spill-slot, offset: 32, size: 4, alignment: 4 }
|
||||||
|
# RESULT-NEXT: - { id: 3, type: spill-slot, offset: 36, size: 4, alignment: 4, stack-id: sgpr-spill }
|
||||||
|
# RESULT-NEXT: - { id: 4, name: dynamic_alloca, type: variable-sized, alignment: 64 }
|
||||||
|
# RESULT-NEXT: - { id: 5, name: m1, size: 2052, alignment: 4, local-offset: 0 }
|
||||||
|
# RESULT-NEXT: - { id: 6, name: m2, size: 2060, alignment: 32, local-offset: 2080 }
|
||||||
|
# RESULT-NEXT: - { id: 7, offset: 48, size: 4, alignment: 4, callee-saved-register: '$sgpr40' }
|
||||||
|
# RESULT-NEXT: - { id: 8, offset: 52, size: 4, alignment: 4, callee-saved-register: '$sgpr41',
|
||||||
|
# RESULT-NEXT: callee-saved-restored: false }
|
||||||
|
# RESULT-NEXT: - { id: 9, name: guard, offset: 128, size: 4, alignment: 4 }
|
||||||
|
|
||||||
|
|
||||||
|
# RESULT: S_NOP 0
|
||||||
|
# RESULT-NEXT: [[FI0:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.1, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0.bigalloca, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI2:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.2, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI3:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.3, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI4:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.4.dynamic_alloca, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI5:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.5.m1, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI6:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.6.m2, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI7:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.7, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI8:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.8, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI9:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %fixed-stack.2, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI10:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %fixed-stack.3, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI11:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %fixed-stack.4, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI12:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %fixed-stack.1, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI13:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %fixed-stack.0, implicit $exec
|
||||||
|
# RESULT-NEXT: [[FI14:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.9.guard, implicit $exec
|
||||||
|
# RESULT-NEXT: S_ENDPGM 0, implicit [[FI0]], implicit [[FI1]], implicit [[FI2]], implicit [[FI3]], implicit [[FI4]], implicit [[FI5]], implicit [[FI6]], implicit [[FI7]], implicit [[FI8]], implicit [[FI9]], implicit [[FI10]], implicit [[FI11]], implicit [[FI12]], implicit [[FI13]], implicit [[FI14]]
|
||||||
|
--- |
|
||||||
|
define void @func(i32 %size) !dbg !5 {
|
||||||
|
%bigalloca = alloca [4 x i32], align 1, addrspace(5)
|
||||||
|
%dynamic_alloca = alloca i32, i32 %size, align 1, addrspace(5)
|
||||||
|
%dead = alloca i64, align 1, addrspace(5)
|
||||||
|
%m1 = alloca [513 x float], align 1, addrspace(5)
|
||||||
|
%m2 = alloca [513 x float], align 1, addrspace(5)
|
||||||
|
%guard = alloca i32, align 4, addrspace(5)
|
||||||
|
call void @llvm.dbg.declare(metadata i32 addrspace(5)* undef, metadata !8, metadata !DIExpression()), !dbg !10
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
|
||||||
|
|
||||||
|
attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn }
|
||||||
|
|
||||||
|
!llvm.dbg.cu = !{!0}
|
||||||
|
!llvm.module.flags = !{!2, !3, !4}
|
||||||
|
|
||||||
|
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||||
|
!1 = !DIFile(filename: "tmp.c", directory: "/dev/null")
|
||||||
|
!2 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||||
|
!4 = !{i32 7, !"PIC Level", i32 2}
|
||||||
|
!5 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0)
|
||||||
|
!6 = !DISubroutineType(types: !7)
|
||||||
|
!7 = !{null}
|
||||||
|
!8 = !DILocalVariable(name: "in", arg: 1, scope: !5, file: !1, line: 1, type: !9)
|
||||||
|
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||||
|
!10 = !DILocation(line: 1, column: 14, scope: !5)
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: func
|
||||||
|
tracksRegLiveness: true
|
||||||
|
frameInfo:
|
||||||
|
isFrameAddressTaken: true
|
||||||
|
isReturnAddressTaken: true
|
||||||
|
hasStackMap: true
|
||||||
|
hasPatchPoint: true
|
||||||
|
stackSize: 0
|
||||||
|
offsetAdjustment: 128
|
||||||
|
maxAlignment: 1
|
||||||
|
adjustsStack: true
|
||||||
|
hasCalls: true
|
||||||
|
stackProtector: '%stack.9'
|
||||||
|
maxCallFrameSize: 420
|
||||||
|
cvBytesOfCalleeSavedRegisters: 48
|
||||||
|
hasOpaqueSPAdjustment: true
|
||||||
|
hasVAStart: true
|
||||||
|
hasMustTailInVarArgFunc: true
|
||||||
|
hasTailCall: true
|
||||||
|
localFrameSize: 0
|
||||||
|
savePoint: '%bb.1'
|
||||||
|
restorePoint: '%bb.2'
|
||||||
|
|
||||||
|
fixedStack:
|
||||||
|
- { id: 0, offset: 0, size: 8, alignment: 4, isImmutable: true, isAliased: false }
|
||||||
|
- { id: 1, offset: 16, size: 16, alignment: 8, isImmutable: false, isAliased: false }
|
||||||
|
- { id: 2, offset: 48, size: 8, alignment: 4, isImmutable: false, isAliased: true }
|
||||||
|
- { id: 3, offset: 52, size: 4, alignment: 4, callee-saved-register: '$sgpr43', callee-saved-restored: true }
|
||||||
|
- { id: 4, offset: 56, size: 4, alignment: 4, callee-saved-register: '$sgpr44', callee-saved-restored: false }
|
||||||
|
stack:
|
||||||
|
- { id: 1, offset: 16, size: 16, alignment: 8, name: bigalloca }
|
||||||
|
- { id: 0, offset: 64, size: 4, alignment: 16,
|
||||||
|
debug-info-variable: '!8', debug-info-expression: '!DIExpression()',
|
||||||
|
debug-info-location: '!10' }
|
||||||
|
- { id: 2, offset: 32, size: 4, alignment: 4, type: spill-slot }
|
||||||
|
- { id: 3, offset: 36, size: 4, alignment: 4, type: spill-slot, stack-id: sgpr-spill }
|
||||||
|
- { id: 4, type: variable-sized, alignment: 64, name: dynamic_alloca }
|
||||||
|
- { id: 5, name: m1, size: 2052, alignment: 4, local-offset: 0 }
|
||||||
|
- { id: 6, name: m2, size: 2060, alignment: 32, local-offset: 2080 }
|
||||||
|
- { id: 7, offset: 48, size: 4, alignment: 4, callee-saved-register: '$sgpr40', callee-saved-restored: true}
|
||||||
|
- { id: 8, offset: 52, size: 4, alignment: 4, callee-saved-register: '$sgpr41', callee-saved-restored: false}
|
||||||
|
- { id: 9, offset: 128, size: 4, alignment: 4, name: guard }
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
S_NOP 0
|
||||||
|
%0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec
|
||||||
|
%1:vgpr_32 = V_MOV_B32_e32 %stack.1, implicit $exec
|
||||||
|
%2:vgpr_32 = V_MOV_B32_e32 %stack.2, implicit $exec
|
||||||
|
%3:vgpr_32 = V_MOV_B32_e32 %stack.3, implicit $exec
|
||||||
|
%4:vgpr_32 = V_MOV_B32_e32 %stack.4, implicit $exec
|
||||||
|
%5:vgpr_32 = V_MOV_B32_e32 %stack.5, implicit $exec
|
||||||
|
%6:vgpr_32 = V_MOV_B32_e32 %stack.6, implicit $exec
|
||||||
|
%7:vgpr_32 = V_MOV_B32_e32 %stack.7, implicit $exec
|
||||||
|
%8:vgpr_32 = V_MOV_B32_e32 %stack.8, implicit $exec
|
||||||
|
%9:vgpr_32 = V_MOV_B32_e32 %fixed-stack.2, implicit $exec
|
||||||
|
%10:vgpr_32 = V_MOV_B32_e32 %fixed-stack.1, implicit $exec
|
||||||
|
%11:vgpr_32 = V_MOV_B32_e32 %fixed-stack.0, implicit $exec
|
||||||
|
%12:vgpr_32 = V_MOV_B32_e32 %fixed-stack.3, implicit $exec
|
||||||
|
%13:vgpr_32 = V_MOV_B32_e32 %fixed-stack.4, implicit $exec
|
||||||
|
%14:vgpr_32 = V_MOV_B32_e32 %stack.9.guard, implicit $exec
|
||||||
|
S_ENDPGM 0, implicit %0, implicit %1, implicit %2, implicit %3, implicit %4, implicit %5, implicit %6, implicit %7, implicit %8, implicit %9, implicit %10, implicit %11, implicit %12, implicit %13, implicit %14
|
||||||
|
|
||||||
|
bb.1:
|
||||||
|
S_NOP 0
|
||||||
|
S_WAITCNT 0
|
||||||
|
|
||||||
|
bb.2:
|
||||||
|
S_WAITCNT 0
|
||||||
|
S_NOP 0
|
||||||
|
|
||||||
|
...
|
|
@ -10,6 +10,7 @@
|
||||||
#include "llvm/CodeGen/MIRParser/MIRParser.h"
|
#include "llvm/CodeGen/MIRParser/MIRParser.h"
|
||||||
#include "llvm/CodeGen/MIRPrinter.h"
|
#include "llvm/CodeGen/MIRPrinter.h"
|
||||||
#include "llvm/CodeGen/MachineDominators.h"
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
@ -20,16 +21,127 @@
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Transforms/Utils/Cloning.h"
|
#include "llvm/Transforms/Utils/Cloning.h"
|
||||||
|
|
||||||
|
// FIXME: Preserve frame index numbers. The numbering is off for fixed objects
|
||||||
|
// since they are inserted at the beginning. This would avoid the need for the
|
||||||
|
// Src2DstFrameIndex map and in the future target MFI code wouldn't need to
|
||||||
|
// worry about it either.
|
||||||
|
static void cloneFrameInfo(
|
||||||
|
MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI,
|
||||||
|
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB,
|
||||||
|
DenseMap<int, int> &Src2DstFrameIndex) {
|
||||||
|
DstMFI.setFrameAddressIsTaken(SrcMFI.isFrameAddressTaken());
|
||||||
|
DstMFI.setReturnAddressIsTaken(SrcMFI.isReturnAddressTaken());
|
||||||
|
DstMFI.setHasStackMap(SrcMFI.hasStackMap());
|
||||||
|
DstMFI.setHasPatchPoint(SrcMFI.hasPatchPoint());
|
||||||
|
DstMFI.setUseLocalStackAllocationBlock(
|
||||||
|
SrcMFI.getUseLocalStackAllocationBlock());
|
||||||
|
DstMFI.setOffsetAdjustment(SrcMFI.getOffsetAdjustment());
|
||||||
|
|
||||||
|
DstMFI.ensureMaxAlignment(SrcMFI.getMaxAlign());
|
||||||
|
assert(DstMFI.getMaxAlign() == SrcMFI.getMaxAlign() &&
|
||||||
|
"we need to set exact alignment");
|
||||||
|
|
||||||
|
DstMFI.setAdjustsStack(SrcMFI.adjustsStack());
|
||||||
|
DstMFI.setHasCalls(SrcMFI.hasCalls());
|
||||||
|
DstMFI.setHasOpaqueSPAdjustment(SrcMFI.hasOpaqueSPAdjustment());
|
||||||
|
DstMFI.setHasCopyImplyingStackAdjustment(
|
||||||
|
SrcMFI.hasCopyImplyingStackAdjustment());
|
||||||
|
DstMFI.setHasVAStart(SrcMFI.hasVAStart());
|
||||||
|
DstMFI.setHasMustTailInVarArgFunc(SrcMFI.hasMustTailInVarArgFunc());
|
||||||
|
DstMFI.setHasTailCall(SrcMFI.hasTailCall());
|
||||||
|
DstMFI.setMaxCallFrameSize(SrcMFI.getMaxCallFrameSize());
|
||||||
|
|
||||||
|
DstMFI.setCVBytesOfCalleeSavedRegisters(
|
||||||
|
SrcMFI.getCVBytesOfCalleeSavedRegisters());
|
||||||
|
|
||||||
|
if (MachineBasicBlock *SavePt = SrcMFI.getSavePoint())
|
||||||
|
DstMFI.setSavePoint(Src2DstMBB.find(SavePt)->second);
|
||||||
|
if (MachineBasicBlock *RestorePt = SrcMFI.getRestorePoint())
|
||||||
|
DstMFI.setRestorePoint(Src2DstMBB.find(RestorePt)->second);
|
||||||
|
|
||||||
|
for (int i = SrcMFI.getObjectIndexBegin(), e = SrcMFI.getObjectIndexEnd();
|
||||||
|
i != e; ++i) {
|
||||||
|
int NewFI;
|
||||||
|
|
||||||
|
if (SrcMFI.isFixedObjectIndex(i)) {
|
||||||
|
NewFI = DstMFI.CreateFixedObject(
|
||||||
|
SrcMFI.getObjectSize(i), SrcMFI.getObjectOffset(i),
|
||||||
|
SrcMFI.isImmutableObjectIndex(i), SrcMFI.isAliasedObjectIndex(i));
|
||||||
|
} else if (SrcMFI.isVariableSizedObjectIndex(i)) {
|
||||||
|
NewFI = DstMFI.CreateVariableSizedObject(SrcMFI.getObjectAlign(i),
|
||||||
|
SrcMFI.getObjectAllocation(i));
|
||||||
|
} else {
|
||||||
|
NewFI = DstMFI.CreateStackObject(
|
||||||
|
SrcMFI.getObjectSize(i), SrcMFI.getObjectAlign(i),
|
||||||
|
SrcMFI.isSpillSlotObjectIndex(i), SrcMFI.getObjectAllocation(i),
|
||||||
|
SrcMFI.getStackID(i));
|
||||||
|
DstMFI.setObjectOffset(NewFI, SrcMFI.getObjectOffset(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SrcMFI.isStatepointSpillSlotObjectIndex(i))
|
||||||
|
DstMFI.markAsStatepointSpillSlotObjectIndex(NewFI);
|
||||||
|
DstMFI.setObjectSSPLayout(NewFI, SrcMFI.getObjectSSPLayout(i));
|
||||||
|
DstMFI.setObjectZExt(NewFI, SrcMFI.isObjectZExt(i));
|
||||||
|
DstMFI.setObjectSExt(NewFI, SrcMFI.isObjectSExt(i));
|
||||||
|
|
||||||
|
Src2DstFrameIndex[i] = NewFI;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned I = 0, E = SrcMFI.getLocalFrameObjectCount(); I < E; ++I) {
|
||||||
|
auto LocalObject = SrcMFI.getLocalFrameObjectMap(I);
|
||||||
|
DstMFI.mapLocalFrameObject(LocalObject.first, LocalObject.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remap the frame indexes in the CalleeSavedInfo
|
||||||
|
std::vector<CalleeSavedInfo> CalleeSavedInfos = SrcMFI.getCalleeSavedInfo();
|
||||||
|
for (CalleeSavedInfo &CSInfo : CalleeSavedInfos) {
|
||||||
|
if (!CSInfo.isSpilledToReg())
|
||||||
|
CSInfo.setFrameIdx(Src2DstFrameIndex[CSInfo.getFrameIdx()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DstMFI.setCalleeSavedInfo(std::move(CalleeSavedInfos));
|
||||||
|
|
||||||
|
if (SrcMFI.hasStackProtectorIndex()) {
|
||||||
|
DstMFI.setStackProtectorIndex(
|
||||||
|
Src2DstFrameIndex[SrcMFI.getStackProtectorIndex()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Needs test, missing MIR serialization.
|
||||||
|
if (SrcMFI.hasFunctionContextIndex()) {
|
||||||
|
DstMFI.setFunctionContextIndex(
|
||||||
|
Src2DstFrameIndex[SrcMFI.getFunctionContextIndex()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF) {
|
static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF) {
|
||||||
auto DstMF = std::make_unique<MachineFunction>(
|
auto DstMF = std::make_unique<MachineFunction>(
|
||||||
SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(),
|
SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(),
|
||||||
SrcMF->getFunctionNumber(), SrcMF->getMMI());
|
SrcMF->getFunctionNumber(), SrcMF->getMMI());
|
||||||
DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB;
|
DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB;
|
||||||
DenseMap<Register, Register> Src2DstReg;
|
DenseMap<Register, Register> Src2DstReg;
|
||||||
|
DenseMap<int, int> Src2DstFrameIndex;
|
||||||
|
|
||||||
auto *SrcMRI = &SrcMF->getRegInfo();
|
auto *SrcMRI = &SrcMF->getRegInfo();
|
||||||
auto *DstMRI = &DstMF->getRegInfo();
|
auto *DstMRI = &DstMF->getRegInfo();
|
||||||
|
|
||||||
|
// Clone blocks.
|
||||||
|
for (MachineBasicBlock &SrcMBB : *SrcMF)
|
||||||
|
Src2DstMBB[&SrcMBB] = DstMF->CreateMachineBasicBlock();
|
||||||
|
|
||||||
|
const MachineFrameInfo &SrcMFI = SrcMF->getFrameInfo();
|
||||||
|
MachineFrameInfo &DstMFI = DstMF->getFrameInfo();
|
||||||
|
|
||||||
|
// Copy stack objects and other info
|
||||||
|
cloneFrameInfo(DstMFI, SrcMFI, Src2DstMBB, Src2DstFrameIndex);
|
||||||
|
|
||||||
|
// Remap the debug info frame index references.
|
||||||
|
DstMF->VariableDbgInfos = SrcMF->VariableDbgInfos;
|
||||||
|
for (MachineFunction::VariableDbgInfo &DbgInfo : DstMF->VariableDbgInfos)
|
||||||
|
DbgInfo.Slot = Src2DstFrameIndex[DbgInfo.Slot];
|
||||||
|
|
||||||
|
// FIXME: Need to clone MachineFunctionInfo, which may also depend on frame
|
||||||
|
// index and block mapping.
|
||||||
|
|
||||||
// Create vregs.
|
// Create vregs.
|
||||||
for (auto &SrcMBB : *SrcMF) {
|
for (auto &SrcMBB : *SrcMF) {
|
||||||
for (auto &SrcMI : SrcMBB) {
|
for (auto &SrcMI : SrcMBB) {
|
||||||
|
@ -75,9 +187,6 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone blocks.
|
|
||||||
for (auto &SrcMBB : *SrcMF)
|
|
||||||
Src2DstMBB[&SrcMBB] = DstMF->CreateMachineBasicBlock();
|
|
||||||
// Link blocks.
|
// Link blocks.
|
||||||
for (auto &SrcMBB : *SrcMF) {
|
for (auto &SrcMBB : *SrcMF) {
|
||||||
auto *DstMBB = Src2DstMBB[&SrcMBB];
|
auto *DstMBB = Src2DstMBB[&SrcMBB];
|
||||||
|
@ -110,7 +219,11 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF) {
|
||||||
// Update MBB.
|
// Update MBB.
|
||||||
if (DstMO.isMBB()) {
|
if (DstMO.isMBB()) {
|
||||||
DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
|
DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
|
||||||
|
} else if (DstMO.isFI()) {
|
||||||
|
// Update frame indexes
|
||||||
|
DstMO.setIndex(Src2DstFrameIndex[DstMO.getIndex()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DstMI->addOperand(DstMO);
|
DstMI->addOperand(DstMO);
|
||||||
}
|
}
|
||||||
DstMI->setMemRefs(*DstMF, SrcMI.memoperands());
|
DstMI->setMemRefs(*DstMF, SrcMI.memoperands());
|
||||||
|
|
Loading…
Reference in New Issue