[llvm] ef658eb - MIR Statepoint refactoring. Part 1: Basic MI level changes.

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 10:58:03 PDT 2020


Author: Denis Antrushin
Date: 2020-07-17T00:57:21+07:00
New Revision: ef658ebd6292f2c555ad774d68705d307c1f2fbf

URL: https://github.com/llvm/llvm-project/commit/ef658ebd6292f2c555ad774d68705d307c1f2fbf
DIFF: https://github.com/llvm/llvm-project/commit/ef658ebd6292f2c555ad774d68705d307c1f2fbf.diff

LOG: MIR Statepoint refactoring. Part 1: Basic MI level changes.

Basic support for variadic-def MIR Statepoint:
- Change TableGen STATEPOINT description to variadic out list
  (For self-documentation purpose; by itself it does not affect
  code generation in any way).
- Update StatepointOpers helper class to handle variadic defs.
- Update MachineVerifier to properly handle them, too.

With this change, new Statepoint instruction can be passed through
backend (excluding ISEL) without errors.

Full change set is available at D81603.
Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D81645

Added: 
    llvm/test/CodeGen/X86/statepoint-vreg.mir

Modified: 
    llvm/include/llvm/CodeGen/StackMaps.h
    llvm/include/llvm/Target/Target.td
    llvm/lib/CodeGen/MachineVerifier.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/StackMaps.h b/llvm/include/llvm/CodeGen/StackMaps.h
index e33ee226e41a..ce4eb85d6452 100644
--- a/llvm/include/llvm/CodeGen/StackMaps.h
+++ b/llvm/include/llvm/CodeGen/StackMaps.h
@@ -166,21 +166,23 @@ class StatepointOpers {
   enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
 
 public:
-  explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
+  explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {
+    NumDefs = MI->getNumDefs();
+  }
 
   /// Get index of statepoint ID operand.
-  unsigned getIDPos() const { return IDPos; }
+  unsigned getIDPos() const { return NumDefs + IDPos; }
 
   /// Get index of Num Patch Bytes operand.
-  unsigned getNBytesPos() const { return NBytesPos; }
+  unsigned getNBytesPos() const { return NumDefs + NBytesPos; }
 
   /// Get index of Num Call Arguments operand.
-  unsigned getNCallArgsPos() const { return NCallArgsPos; }
+  unsigned getNCallArgsPos() const { return NumDefs + NCallArgsPos; }
 
   /// Get starting index of non call related arguments
   /// (calling convention, statepoint flags, vm state and gc state).
   unsigned getVarIdx() const {
-    return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
+    return MI->getOperand(NumDefs + NCallArgsPos).getImm() + MetaEnd + NumDefs;
   }
 
   /// Get index of Calling Convention operand.
@@ -195,16 +197,16 @@ class StatepointOpers {
   }
 
   /// Return the ID for the given statepoint.
-  uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
+  uint64_t getID() const { return MI->getOperand(NumDefs + IDPos).getImm(); }
 
   /// Return the number of patchable bytes the given statepoint should emit.
   uint32_t getNumPatchBytes() const {
-    return MI->getOperand(NBytesPos).getImm();
+    return MI->getOperand(NumDefs + NBytesPos).getImm();
   }
 
   /// Return the target of the underlying call.
   const MachineOperand &getCallTarget() const {
-    return MI->getOperand(CallTargetPos);
+    return MI->getOperand(NumDefs + CallTargetPos);
   }
 
   /// Return the calling convention.
@@ -217,6 +219,7 @@ class StatepointOpers {
 
 private:
   const MachineInstr *MI;
+  unsigned NumDefs;
 };
 
 class StackMaps {

diff  --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index aab5376db453..16a817980f7c 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -1157,7 +1157,7 @@ def PATCHPOINT : StandardPseudoInstruction {
   let usesCustomInserter = 1;
 }
 def STATEPOINT : StandardPseudoInstruction {
-  let OutOperandList = (outs);
+  let OutOperandList = (outs variable_ops);
   let InOperandList = (ins variable_ops);
   let usesCustomInserter = 1;
   let mayLoad = 1;

diff  --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index c1a2c4e0bc6e..63f534f20a71 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1565,6 +1565,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
   if (MCID.getOpcode() == TargetOpcode::PATCHPOINT)
     NumDefs = (MONum == 0 && MO->isReg()) ? NumDefs : 0;
 
+  if (MCID.getOpcode() == TargetOpcode::STATEPOINT)
+    NumDefs = MI->getNumDefs();
+
   // The first MCID.NumDefs operands must be explicit register defines
   if (MONum < NumDefs) {
     const MCOperandInfo &MCOI = MCID.OpInfo[MONum];

diff  --git a/llvm/test/CodeGen/X86/statepoint-vreg.mir b/llvm/test/CodeGen/X86/statepoint-vreg.mir
new file mode 100644
index 000000000000..311a71205f2a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/statepoint-vreg.mir
@@ -0,0 +1,156 @@
+# NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+# RUN: llc -o - %s -start-after=finalize-isel | FileCheck %s
+
+--- |
+  ; ModuleID = 'test/CodeGen/X86/statepoint-vreg.ll'
+  source_filename = "test/CodeGen/X86/statepoint-vreg.ll"
+  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-pc-linux-gnu"
+
+  declare void @bar()
+
+  define i32 @test_basic(i32 addrspace(1)* %obj1, i32 addrspace(1)* %obj2) gc "statepoint-example" {
+  ; CHECK-LABEL: test_basic:
+  ; CHECK:       # %bb.0:
+  ; CHECK-NEXT:    pushq %r14
+  ; CHECK-NEXT:    .cfi_def_cfa_offset 16
+  ; CHECK-NEXT:    pushq %rbx
+  ; CHECK-NEXT:    .cfi_def_cfa_offset 24
+  ; CHECK-NEXT:    pushq %rax
+  ; CHECK-NEXT:    .cfi_def_cfa_offset 32
+  ; CHECK-NEXT:    .cfi_offset %rbx, -24
+  ; CHECK-NEXT:    .cfi_offset %r14, -16
+  ; CHECK-NEXT:    movq %rsi, %r14
+  ; CHECK-NEXT:    movq %rdi, %rbx
+  ; CHECK-NEXT:    callq bar
+  ; CHECK-NEXT:  .Ltmp0:
+  ; CHECK-NEXT:    movl (%rbx), %eax
+  ; CHECK-NEXT:    addl (%r14), %eax
+  ; CHECK-NEXT:    addq $8, %rsp
+  ; CHECK-NEXT:    .cfi_def_cfa_offset 24
+  ; CHECK-NEXT:    popq %rbx
+  ; CHECK-NEXT:    .cfi_def_cfa_offset 16
+  ; CHECK-NEXT:    popq %r14
+  ; CHECK-NEXT:    .cfi_def_cfa_offset 8
+  ; CHECK-NEXT:    retq
+    %token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i32 addrspace(1)* %obj1, i32 addrspace(1)* %obj2) ]
+    %rel1 = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token, i32 0, i32 0) ; (%obj1, %obj1)
+    %rel2 = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token, i32 1, i32 1) ; (%obj2, %obj2)
+    %a = load i32, i32 addrspace(1)* %rel1, align 4
+    %b = load i32, i32 addrspace(1)* %rel2, align 4
+    %c = add i32 %a, %b
+    ret i32 %c
+  }
+
+  ; CHECK-LABEL:  __LLVM_StackMaps:
+  ; CHECK-NEXT:    .byte	3
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	1
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .long	1
+  ; CHECK-NEXT:    .quad	test_basic
+  ; CHECK-NEXT:    .quad	24
+  ; CHECK-NEXT:    .quad	1
+  ; CHECK-NEXT:    .quad	2882400000
+  ; CHECK-NEXT:    .long	.Ltmp0-test_basic
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .byte	4
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .byte	4
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .byte	4
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	1
+  ; CHECK-NEXT:    .byte	4
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .byte	1
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	14
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .byte	1
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	14
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .byte	1
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	3
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .byte	1
+  ; CHECK-NEXT:    .byte	0
+  ; CHECK-NEXT:    .short	8
+  ; CHECK-NEXT:    .short	3
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .long	0
+  ; CHECK-NEXT:    .p2align	3
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .short	0
+  ; CHECK-NEXT:    .p2align	3
+
+  declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 immarg, i32 immarg, void ()*, i32 immarg, i32 immarg, ...)
+
+  ; Function Attrs: nounwind readonly
+  declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32 immarg, i32 immarg) #0
+
+  attributes #0 = { nounwind readonly }
+  attributes #1 = { nounwind }
+
+...
+---
+name:            test_basic
+alignment:       16
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr64, preferred-register: '' }
+  - { id: 1, class: gr64, preferred-register: '' }
+  - { id: 2, class: gr64, preferred-register: '' }
+  - { id: 3, class: gr64, preferred-register: '' }
+  - { id: 4, class: gr32, preferred-register: '' }
+  - { id: 5, class: gr32, preferred-register: '' }
+liveins:
+  - { reg: '$rdi', virtual-reg: '%0' }
+  - { reg: '$rsi', virtual-reg: '%1' }
+fixedStack:      []
+stack:           []
+callSites:       []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0 (%ir-block.0):
+    liveins: $rdi, $rsi
+
+    %1:gr64 = COPY $rsi
+    %0:gr64 = COPY $rdi
+    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+    %2:gr64, %3:gr64 = STATEPOINT 2882400000, 0, 0, @bar, 2, 0, 2, 0, 2, 1, 2, 0, %1, %1(tied-def 0), %0, %0(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp
+    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+    %4:gr32 = MOV32rm killed %3, 1, $noreg, 0, $noreg :: (load 4 from %ir.rel1, addrspace 1)
+    %5:gr32 = ADD32rm %4, killed %2, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load 4 from %ir.rel2, addrspace 1)
+    $eax = COPY %5
+    RET 0, $eax
+
+...


        


More information about the llvm-commits mailing list