[llvm] r364506 - [MachineFunction] Base support for call site info tracking

Djordje Todorovic via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 27 00:48:06 PDT 2019


Author: djtodoro
Date: Thu Jun 27 00:48:06 2019
New Revision: 364506

URL: http://llvm.org/viewvc/llvm-project?rev=364506&view=rev
Log:
[MachineFunction] Base support for call site info tracking

Add an attribute into the MachineFunction that tracks call site info.

([8/13] Introduce the debug entry values.)

Co-authored-by: Ananth Sowda <asowda at cisco.com>
Co-authored-by: Nikola Prica <nikola.prica at rt-rk.com>
Co-authored-by: Ivan Baev <ibaev at cisco.com>

Differential Revision: https://reviews.llvm.org/D61061

Added:
    llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error1.mir
    llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error2.mir
    llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error3.mir
    llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error4.mir
Modified:
    llvm/trunk/docs/MIRLangRef.rst
    llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
    llvm/trunk/include/llvm/CodeGen/MachineFunction.h
    llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp
    llvm/trunk/lib/CodeGen/MachineVerifier.cpp

Modified: llvm/trunk/docs/MIRLangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/MIRLangRef.rst?rev=364506&r1=364505&r2=364506&view=diff
==============================================================================
--- llvm/trunk/docs/MIRLangRef.rst (original)
+++ llvm/trunk/docs/MIRLangRef.rst Thu Jun 27 00:48:06 2019
@@ -191,6 +191,9 @@ of such YAML document:
      tracksRegLiveness: true
      liveins:
        - { reg: '$rdi' }
+     callSites:
+       - { bb: 0, offset: 3, fwdArgRegs:
+           - { arg: 0, reg: '$edi' } }
      body: |
        bb.0.entry:
          liveins: $rdi
@@ -198,6 +201,7 @@ of such YAML document:
          $eax = MOV32rm $rdi, 1, _, 0, _
          $eax = INC32r killed $eax, implicit-def dead $eflags
          MOV32mr killed $rdi, 1, _, 0, _, $eax
+         CALL64pcrel32 @foo <regmask...>
          RETQ $eax
      ...
 
@@ -210,6 +214,9 @@ name of a function that this machine fun
 The attribute ``body`` is a `YAML block literal string`_. Its value represents
 the function's machine basic blocks and their machine instructions.
 
+The attribute ``callSites`` is a representation of call site information which
+keeps track of call instructions and registers used to transfer call arguments.
+
 Machine Instructions Format Reference
 =====================================
 

Modified: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h?rev=364506&r1=364505&r2=364506&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Thu Jun 27 00:48:06 2019
@@ -347,6 +347,66 @@ template <> struct MappingTraits<FixedMa
   static const bool flow = true;
 };
 
+
+/// Serializable representation of CallSiteInfo.
+struct CallSiteInfo {
+  // Representation of call argument and register which is used to
+  // transfer it.
+  struct ArgRegPair {
+    StringValue Reg;
+    uint16_t ArgNo;
+
+    bool operator==(const ArgRegPair &Other) const {
+      return Reg == Other.Reg && ArgNo == Other.ArgNo;
+    }
+  };
+
+  /// Identifies call instruction location in machine function.
+  struct MachineInstrLoc {
+    unsigned BlockNum;
+    unsigned Offset;
+
+    bool operator==(const MachineInstrLoc &Other) const {
+      return BlockNum == Other.BlockNum && Offset == Other.Offset;
+    }
+  };
+
+  MachineInstrLoc CallLocation;
+  std::vector<ArgRegPair> ArgForwardingRegs;
+
+  bool operator==(const CallSiteInfo &Other) const {
+    return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
+           CallLocation.Offset == Other.CallLocation.Offset;
+  }
+};
+
+template <> struct MappingTraits<CallSiteInfo::ArgRegPair> {
+  static void mapping(IO &YamlIO, CallSiteInfo::ArgRegPair &ArgReg) {
+    YamlIO.mapRequired("arg", ArgReg.ArgNo);
+    YamlIO.mapRequired("reg", ArgReg.Reg);
+  }
+
+  static const bool flow = true;
+};
+}
+}
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo::ArgRegPair)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<CallSiteInfo> {
+  static void mapping(IO &YamlIO, CallSiteInfo &CSInfo) {
+    YamlIO.mapRequired("bb", CSInfo.CallLocation.BlockNum);
+    YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
+    YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
+                       std::vector<CallSiteInfo::ArgRegPair>());
+  }
+
+  static const bool flow = true;
+};
+
 struct MachineConstantPoolValue {
   UnsignedValue ID;
   StringValue Value;
@@ -401,6 +461,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml:
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry)
 
@@ -529,6 +590,7 @@ struct MachineFunction {
   std::vector<MachineStackObject> StackObjects;
   std::vector<MachineConstantPoolValue> Constants; /// Constant pool.
   std::unique_ptr<MachineFunctionInfo> MachineFuncInfo;
+  std::vector<CallSiteInfo> CallSitesInfo;
   MachineJumpTable JumpTableInfo;
   BlockStringValue Body;
 };
@@ -555,6 +617,8 @@ template <> struct MappingTraits<Machine
                        std::vector<FixedMachineStackObject>());
     YamlIO.mapOptional("stack", MF.StackObjects,
                        std::vector<MachineStackObject>());
+    YamlIO.mapOptional("callSites", MF.CallSitesInfo,
+                       std::vector<CallSiteInfo>());
     YamlIO.mapOptional("constants", MF.Constants,
                        std::vector<MachineConstantPoolValue>());
     YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo);

Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=364506&r1=364505&r2=364506&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Thu Jun 27 00:48:06 2019
@@ -378,9 +378,28 @@ public:
     virtual void MF_HandleRemoval(MachineInstr &MI) = 0;
   };
 
+  /// Structure used to represent pair of argument number after call lowering
+  /// and register used to transfer that argument.
+  /// For now we support only cases when argument is transferred through one
+  /// register.
+  struct ArgRegPair {
+    unsigned Reg;
+    uint16_t ArgNo;
+    ArgRegPair(unsigned R, unsigned Arg) : Reg(R), ArgNo(Arg) {
+      assert(Arg < (1 << 16) && "Arg out of range");
+    }
+  };
+  /// Vector of call argument and its forwarding register.
+  using CallSiteInfo = SmallVector<ArgRegPair, 1>;
+  using CallSiteInfoImpl = SmallVectorImpl<ArgRegPair>;
+
 private:
   Delegate *TheDelegate = nullptr;
 
+  using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
+  /// Map a call instruction to call site arguments forwarding info.
+  CallSiteInfoMap CallSitesInfo;
+
   // Callbacks for insertion and removal.
   void handleInsertion(MachineInstr &MI);
   void handleRemoval(MachineInstr &MI);
@@ -946,6 +965,17 @@ public:
   const VariableDbgInfoMapTy &getVariableDbgInfo() const {
     return VariableDbgInfos;
   }
+
+  void addCallArgsForwardingRegs(const MachineInstr *CallI,
+                                 CallSiteInfoImpl &&CallInfo) {
+    assert(CallI->isCall());
+    CallSitesInfo[CallI] = std::move(CallInfo);
+  }
+
+  const CallSiteInfoMap &getCallSitesInfo() const {
+    return CallSitesInfo;
+  }
+
 };
 
 //===--------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=364506&r1=364505&r2=364506&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Thu Jun 27 00:48:06 2019
@@ -116,6 +116,9 @@ public:
   bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
                            const yaml::MachineFunction &YamlMF);
 
+  bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,
+                              const yaml::MachineFunction &YamlMF);
+
   bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
                                 std::vector<CalleeSavedInfo> &CSIInfo,
                                 const yaml::StringValue &RegisterSource,
@@ -337,6 +340,47 @@ void MIRParserImpl::computeFunctionPrope
     Properties.set(MachineFunctionProperties::Property::NoVRegs);
 }
 
+bool MIRParserImpl::initializeCallSiteInfo(
+    PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) {
+  MachineFunction &MF = PFS.MF;
+  SMDiagnostic Error;
+  const LLVMTargetMachine &TM = MF.getTarget();
+  for (auto YamlCSInfo : YamlMF.CallSitesInfo) {
+    yaml::CallSiteInfo::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;
+    if (MILoc.BlockNum >= MF.size())
+      return error(Twine(MF.getName()) +
+                   Twine(" call instruction block out of range.") +
+                   " Unable to reference bb:" + Twine(MILoc.BlockNum));
+    auto CallB = std::next(MF.begin(), MILoc.BlockNum);
+    if (MILoc.Offset >= CallB->size())
+      return error(Twine(MF.getName()) +
+                   Twine(" call instruction offset out of range.") +
+                   "Unable to reference instruction at bb: " +
+                   Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset));
+    auto CallI = std::next(CallB->begin(), MILoc.Offset);
+    if (!CallI->isCall())
+      return error(Twine(MF.getName()) +
+                   Twine(" call site info should reference call "
+                         "instruction. Instruction at bb:") +
+                   Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
+                   " is not a call instruction");
+    MachineFunction::CallSiteInfo CSInfo;
+    for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
+      unsigned Reg = 0;
+      if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))
+        return error(Error, ArgRegPair.Reg.SourceRange);
+      CSInfo.emplace_back(Reg, ArgRegPair.ArgNo);
+    }
+
+    if (TM.Options.EnableDebugEntryValues)
+      MF.addCallArgsForwardingRegs(&*CallI, std::move(CSInfo));
+  }
+
+  if (YamlMF.CallSitesInfo.size() && !TM.Options.EnableDebugEntryValues)
+    return error(Twine("Call site info provided but not used"));
+  return false;
+}
+
 bool
 MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
                                          MachineFunction &MF) {
@@ -437,6 +481,9 @@ MIRParserImpl::initializeMachineFunction
 
   computeFunctionProperties(MF);
 
+  if (initializeCallSiteInfo(PFS, YamlMF))
+    return false;
+
   MF.getSubtarget().mirFileLoaded(MF);
 
   MF.verify();

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=364506&r1=364505&r2=364506&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Thu Jun 27 00:48:06 2019
@@ -129,6 +129,9 @@ public:
                const MachineJumpTableInfo &JTI);
   void convertStackObjects(yaml::MachineFunction &YMF,
                            const MachineFunction &MF, ModuleSlotTracker &MST);
+  void convertCallSiteObjects(yaml::MachineFunction &YMF,
+                              const MachineFunction &MF,
+                              ModuleSlotTracker &MST);
 
 private:
   void initRegisterMaskIds(const MachineFunction &MF);
@@ -212,6 +215,7 @@ void MIRPrinter::print(const MachineFunc
   MST.incorporateFunction(MF.getFunction());
   convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
   convertStackObjects(YamlMF, MF, MST);
+  convertCallSiteObjects(YamlMF, MF, MST);
   if (const auto *ConstantPool = MF.getConstantPool())
     convert(YamlMF, *ConstantPool);
   if (const auto *JumpTableInfo = MF.getJumpTableInfo())
@@ -460,6 +464,39 @@ void MIRPrinter::convertStackObjects(yam
   }
 }
 
+void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF,
+                                        const MachineFunction &MF,
+                                        ModuleSlotTracker &MST) {
+  const auto *TRI = MF.getSubtarget().getRegisterInfo();
+  for (auto CSInfo : MF.getCallSitesInfo()) {
+    yaml::CallSiteInfo YmlCS;
+    yaml::CallSiteInfo::MachineInstrLoc CallLocation;
+
+    // Prepare instruction position.
+    MachineBasicBlock::const_iterator CallI = CSInfo.first->getIterator();
+    CallLocation.BlockNum = CallI->getParent()->getNumber();
+    // Get call instruction offset from the beginning of block.
+    CallLocation.Offset = std::distance(CallI->getParent()->begin(), CallI);
+    YmlCS.CallLocation = CallLocation;
+    // Construct call arguments and theirs forwarding register info.
+    for (auto ArgReg : CSInfo.second) {
+      yaml::CallSiteInfo::ArgRegPair YmlArgReg;
+      YmlArgReg.ArgNo = ArgReg.ArgNo;
+      printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
+      YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
+    }
+    YMF.CallSitesInfo.push_back(YmlCS);
+  }
+
+  // Sort call info by position of call instructions.
+  llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(),
+             [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) {
+               if (A.CallLocation.BlockNum == B.CallLocation.BlockNum)
+                 return A.CallLocation.Offset < B.CallLocation.Offset;
+               return A.CallLocation.BlockNum < B.CallLocation.BlockNum;
+             });
+}
+
 void MIRPrinter::convert(yaml::MachineFunction &MF,
                          const MachineConstantPool &ConstantPool) {
   unsigned ID = 0;

Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=364506&r1=364505&r2=364506&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Thu Jun 27 00:48:06 2019
@@ -2193,6 +2193,10 @@ void MachineVerifier::visitMachineFuncti
     verifyLiveVariables();
   if (LiveInts)
     verifyLiveIntervals();
+
+  for (auto CSInfo : MF->getCallSitesInfo())
+    if (!CSInfo.first->isCall())
+      report("Call site info referencing instruction that is not call", MF);
 }
 
 void MachineVerifier::verifyLiveVariables() {

Added: llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error1.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error1.mir?rev=364506&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error1.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error1.mir Thu Jun 27 00:48:06 2019
@@ -0,0 +1,23 @@
+# RUN: not llc -mtriple=x86_64-- -run-pass none -debug-entry-values %s -o - 2>&1 | FileCheck %s
+# CHECK: baa call instruction block out of range. Unable to reference bb:1
+--- |
+  define dso_local i32 @baa(i32 %a) local_unnamed_addr {
+  entry:
+    %call = tail call i32 @foo(i32 %a)
+    ret i32 %call
+  }
+
+  declare dso_local i32 @foo(i32) local_unnamed_addr
+...
+---
+name: baa
+callSites:
+  - {bb: 1, offset: 0, fwdArgRegs:
+    - { arg: 0, reg: '$edi' } }
+body: |
+  bb.0:
+  liveins: $edi
+
+  TAILJMPd64 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rsp, implicit $ssp, implicit $edi
+
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error2.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error2.mir?rev=364506&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error2.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error2.mir Thu Jun 27 00:48:06 2019
@@ -0,0 +1,23 @@
+# RUN: not llc -mtriple=x86_64-- -run-pass none -debug-entry-values %s -o - 2>&1 | FileCheck %s
+# CHECK: baa call instruction offset out of range.Unable to reference instruction at bb: 0 at offset:1
+--- |
+  define dso_local i32 @baa(i32 %a) local_unnamed_addr {
+  entry:
+    %call = tail call i32 @foo(i32 %a)
+    ret i32 %call
+  }
+
+  declare dso_local i32 @foo(i32) local_unnamed_addr
+...
+---
+name: baa
+callSites:
+  - {bb: 0, offset: 1, fwdArgRegs:
+    - { arg: 0, reg: '$edi' } }
+body: |
+  bb.0:
+  liveins: $edi
+
+  TAILJMPd64 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rsp, implicit $ssp, implicit $edi
+
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error3.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error3.mir?rev=364506&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error3.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error3.mir Thu Jun 27 00:48:06 2019
@@ -0,0 +1,23 @@
+# RUN: not llc -mtriple=x86_64-- -run-pass none -debug-entry-values %s -o - 2>&1 | FileCheck %s
+# CHECK: baa call site info should reference call instruction. Instruction at bb:0 at offset:0 is not a call instruction
+--- |
+  define dso_local i32 @baa(i32 %a) local_unnamed_addr {
+  entry:
+    %call = tail call i32 @foo(i32 %a)
+    ret i32 %call
+  }
+
+  declare dso_local i32 @foo(i32) local_unnamed_addr
+...
+---
+name: baa
+callSites:
+  - {bb: 0, offset: 0, fwdArgRegs:
+    - { arg: 0, reg: '$edi' } }
+body: |
+  bb.0:
+  liveins: $edi
+  renamable $edi = nsw ADD32ri8 killed renamable $edi, 4, implicit-def dead $eflags
+  TAILJMPd64 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rsp, implicit $ssp, implicit $edi
+
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error4.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error4.mir?rev=364506&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error4.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/call-site-info-error4.mir Thu Jun 27 00:48:06 2019
@@ -0,0 +1,23 @@
+# RUN: not llc -mtriple=x86_64-- -run-pass none %s -o - 2>&1 | FileCheck %s
+# CHECK: Call site info provided but not used
+--- |
+  define dso_local i32 @baa(i32 %a) local_unnamed_addr {
+  entry:
+    %call = tail call i32 @foo(i32 %a)
+    ret i32 %call
+  }
+
+  declare dso_local i32 @foo(i32) local_unnamed_addr
+...
+---
+name: baa
+callSites:
+  - {bb: 0, offset: 0, fwdArgRegs:
+    - { arg: 0, reg: '$edi' } }
+body: |
+  bb.0:
+  liveins: $edi
+
+  TAILJMPd64 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rsp, implicit $ssp, implicit $edi
+
+...




More information about the llvm-commits mailing list