[llvm-branch-commits] [llvm-branch] r324009 - Merging r323915:

Reid Kleckner via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Feb 1 13:31:35 PST 2018


Author: rnk
Date: Thu Feb  1 13:31:35 2018
New Revision: 324009

URL: http://llvm.org/viewvc/llvm-project?rev=324009&view=rev
Log:
Merging r323915:
------------------------------------------------------------------------
r323915 | chandlerc | 2018-01-31 12:56:37 -0800 (Wed, 31 Jan 2018) | 17 lines

[x86] Make the retpoline thunk insertion a machine function pass.

Summary:
This removes the need for a machine module pass using some deeply
questionable hacks. This should address PR36123 which is a case where in
full LTO the memory usage of a machine module pass actually ended up
being significant.

We should revert this on trunk as soon as we understand and fix the
memory usage issue, but we should include this in any backports of
retpolines themselves.

Reviewers: echristo, MatzeB

Subscribers: sanjoy, mcrosier, mehdi_amini, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D42726
------------------------------------------------------------------------

Modified:
    llvm/branches/release_50/   (props changed)
    llvm/branches/release_50/lib/Target/X86/X86.h
    llvm/branches/release_50/lib/Target/X86/X86RetpolineThunks.cpp
    llvm/branches/release_50/test/CodeGen/X86/O0-pipeline.ll

Propchange: llvm/branches/release_50/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Feb  1 13:31:35 2018
@@ -1,2 +1,2 @@
-/llvm/trunk:313366,323155
+/llvm/trunk:313366,323155,323915
 /llvm/trunk:155241,308483-308484,308503,308808,308813,308847,308891,308906,308950,308963,308978,308986,309044,309071,309113,309120,309122,309140,309227,309302,309321,309323,309325,309330,309343,309353,309355,309422,309481,309483,309495,309555,309561,309594,309614,309651,309744,309758,309849,309928,309930,309945,310066,310071,310190,310240-310242,310250,310253,310262,310267,310481,310492,310498,310510,310534,310552,310604,310712,310779,310784,310796,310842,310906,310926,310939,310979,310988,310990-310991,311061,311068,311071,311087,311229,311258,311263,311387,311429,311554,311565,311572,311623,311835,312022,312285,313334:312337

Modified: llvm/branches/release_50/lib/Target/X86/X86.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/X86/X86.h?rev=324009&r1=324008&r2=324009&view=diff
==============================================================================
--- llvm/branches/release_50/lib/Target/X86/X86.h (original)
+++ llvm/branches/release_50/lib/Target/X86/X86.h Thu Feb  1 13:31:35 2018
@@ -100,7 +100,7 @@ void initializeFixupBWInstPassPass(PassR
 FunctionPass *createX86EvexToVexInsts();
 
 /// This pass creates the thunks for the retpoline feature.
-ModulePass *createX86RetpolineThunksPass();
+FunctionPass *createX86RetpolineThunksPass();
 
 InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM,
                                                   X86Subtarget &,

Modified: llvm/branches/release_50/lib/Target/X86/X86RetpolineThunks.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/lib/Target/X86/X86RetpolineThunks.cpp?rev=324009&r1=324008&r2=324009&view=diff
==============================================================================
--- llvm/branches/release_50/lib/Target/X86/X86RetpolineThunks.cpp (original)
+++ llvm/branches/release_50/lib/Target/X86/X86RetpolineThunks.cpp Thu Feb  1 13:31:35 2018
@@ -38,18 +38,27 @@ using namespace llvm;
 
 #define DEBUG_TYPE "x86-retpoline-thunks"
 
+static const char ThunkNamePrefix[] = "__llvm_retpoline_";
+static const char R11ThunkName[]    = "__llvm_retpoline_r11";
+static const char EAXThunkName[]    = "__llvm_retpoline_eax";
+static const char ECXThunkName[]    = "__llvm_retpoline_ecx";
+static const char EDXThunkName[]    = "__llvm_retpoline_edx";
+static const char PushThunkName[]   = "__llvm_retpoline_push";
+
 namespace {
-class X86RetpolineThunks : public ModulePass {
+class X86RetpolineThunks : public MachineFunctionPass {
 public:
   static char ID;
 
-  X86RetpolineThunks() : ModulePass(ID) {}
+  X86RetpolineThunks() : MachineFunctionPass(ID) {}
 
   StringRef getPassName() const override { return "X86 Retpoline Thunks"; }
 
-  bool runOnModule(Module &M) override;
+  bool doInitialization(Module &M) override;
+  bool runOnMachineFunction(MachineFunction &F) override;
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
+    MachineFunctionPass::getAnalysisUsage(AU);
     AU.addRequired<MachineModuleInfo>();
     AU.addPreserved<MachineModuleInfo>();
   }
@@ -61,51 +70,74 @@ private:
   const X86Subtarget *STI;
   const X86InstrInfo *TII;
 
-  Function *createThunkFunction(Module &M, StringRef Name);
+  bool InsertedThunks;
+
+  void createThunkFunction(Module &M, StringRef Name);
   void insertRegReturnAddrClobber(MachineBasicBlock &MBB, unsigned Reg);
   void insert32BitPushReturnAddrClobber(MachineBasicBlock &MBB);
-  void createThunk(Module &M, StringRef NameSuffix,
-                   Optional<unsigned> Reg = None);
+  void populateThunk(MachineFunction &MF, Optional<unsigned> Reg = None);
 };
 
 } // end anonymous namespace
 
-ModulePass *llvm::createX86RetpolineThunksPass() {
+FunctionPass *llvm::createX86RetpolineThunksPass() {
   return new X86RetpolineThunks();
 }
 
 char X86RetpolineThunks::ID = 0;
 
-bool X86RetpolineThunks::runOnModule(Module &M) {
-  DEBUG(dbgs() << getPassName() << '\n');
+bool X86RetpolineThunks::doInitialization(Module &M) {
+  InsertedThunks = false;
+  return false;
+}
 
-  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
-  assert(TPC && "X86-specific target pass should not be run without a target "
-                "pass config!");
+bool X86RetpolineThunks::runOnMachineFunction(MachineFunction &MF) {
+  DEBUG(dbgs() << getPassName() << '\n');
 
-  MMI = &getAnalysis<MachineModuleInfo>();
-  TM = &TPC->getTM<TargetMachine>();
+  TM = &MF.getTarget();;
+  STI = &MF.getSubtarget<X86Subtarget>();
+  TII = STI->getInstrInfo();
   Is64Bit = TM->getTargetTriple().getArch() == Triple::x86_64;
 
-  // Only add a thunk if we have at least one function that has the retpoline
-  // feature enabled in its subtarget.
-  // FIXME: Conditionalize on indirect calls so we don't emit a thunk when
-  // nothing will end up calling it.
-  // FIXME: It's a little silly to look at every function just to enumerate
-  // the subtargets, but eventually we'll want to look at them for indirect
-  // calls, so maybe this is OK.
-  if (!llvm::any_of(M, [&](const Function &F) {
-        // Save the subtarget we find for use in emitting the subsequent
-        // thunk.
-        STI = &TM->getSubtarget<X86Subtarget>(F);
-        return STI->useRetpoline() && !STI->useRetpolineExternalThunk();
-      }))
-    return false;
+  MMI = &getAnalysis<MachineModuleInfo>();
+  Module &M = const_cast<Module &>(*MMI->getModule());
 
-  // If we have a relevant subtarget, get the instr info as well.
-  TII = STI->getInstrInfo();
+  // If this function is not a thunk, check to see if we need to insert
+  // a thunk.
+  if (!MF.getName().startswith(ThunkNamePrefix)) {
+    // If we've already inserted a thunk, nothing else to do.
+    if (InsertedThunks)
+      return false;
+
+    // Only add a thunk if one of the functions has the retpoline feature
+    // enabled in its subtarget, and doesn't enable external thunks.
+    // FIXME: Conditionalize on indirect calls so we don't emit a thunk when
+    // nothing will end up calling it.
+    // FIXME: It's a little silly to look at every function just to enumerate
+    // the subtargets, but eventually we'll want to look at them for indirect
+    // calls, so maybe this is OK.
+    if (!STI->useRetpoline() || STI->useRetpolineExternalThunk())
+      return false;
+
+    // Otherwise, we need to insert the thunk.
+    // WARNING: This is not really a well behaving thing to do in a function
+    // pass. We extract the module and insert a new function (and machine
+    // function) directly into the module.
+    if (Is64Bit)
+      createThunkFunction(M, R11ThunkName);
+    else
+      for (StringRef Name :
+           {EAXThunkName, ECXThunkName, EDXThunkName, PushThunkName})
+        createThunkFunction(M, Name);
+    InsertedThunks = true;
+    return true;
+  }
 
+  // If this *is* a thunk function, we need to populate it with the correct MI.
   if (Is64Bit) {
+    assert(MF.getName() == "__llvm_retpoline_r11" &&
+           "Should only have an r11 thunk on 64-bit targets");
+
     // __llvm_retpoline_r11:
     //   callq .Lr11_call_target
     // .Lr11_capture_spec:
@@ -116,8 +148,7 @@ bool X86RetpolineThunks::runOnModule(Mod
     // .Lr11_call_target:
     //   movq %r11, (%rsp)
     //   retq
-
-    createThunk(M, "r11", X86::R11);
+    populateThunk(MF, X86::R11);
   } else {
     // For 32-bit targets we need to emit a collection of thunks for various
     // possible scratch registers as well as a fallback that is used when
@@ -161,16 +192,25 @@ bool X86RetpolineThunks::runOnModule(Mod
     //         popl 8(%esp)   # Pop RA to final RA
     //         popl (%esp)    # Pop callee to next top of stack
     //         retl           # Ret to callee
-    createThunk(M, "eax", X86::EAX);
-    createThunk(M, "ecx", X86::ECX);
-    createThunk(M, "edx", X86::EDX);
-    createThunk(M, "push");
+    if (MF.getName() == EAXThunkName)
+      populateThunk(MF, X86::EAX);
+    else if (MF.getName() == ECXThunkName)
+      populateThunk(MF, X86::ECX);
+    else if (MF.getName() == EDXThunkName)
+      populateThunk(MF, X86::EDX);
+    else if (MF.getName() == PushThunkName)
+      populateThunk(MF);
+    else
+      llvm_unreachable("Invalid thunk name on x86-32!");
   }
 
   return true;
 }
 
-Function *X86RetpolineThunks::createThunkFunction(Module &M, StringRef Name) {
+void X86RetpolineThunks::createThunkFunction(Module &M, StringRef Name) {
+  assert(Name.startswith(ThunkNamePrefix) &&
+         "Created a thunk with an unexpected prefix!");
+
   LLVMContext &Ctx = M.getContext();
   auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
   Function *F =
@@ -190,7 +230,6 @@ Function *X86RetpolineThunks::createThun
   IRBuilder<> Builder(Entry);
 
   Builder.CreateRetVoid();
-  return F;
 }
 
 void X86RetpolineThunks::insertRegReturnAddrClobber(MachineBasicBlock &MBB,
@@ -200,6 +239,7 @@ void X86RetpolineThunks::insertRegReturn
   addRegOffset(BuildMI(&MBB, DebugLoc(), TII->get(MovOpc)), SPReg, false, 0)
       .addReg(Reg);
 }
+
 void X86RetpolineThunks::insert32BitPushReturnAddrClobber(
     MachineBasicBlock &MBB) {
   // The instruction sequence we use to replace the return address without
@@ -225,21 +265,16 @@ void X86RetpolineThunks::insert32BitPush
                false, 0);
 }
 
-void X86RetpolineThunks::createThunk(Module &M, StringRef NameSuffix,
-                                     Optional<unsigned> Reg) {
-  Function &F =
-      *createThunkFunction(M, (Twine("__llvm_retpoline_") + NameSuffix).str());
-  MachineFunction &MF = MMI->getOrCreateMachineFunction(F);
-
+void X86RetpolineThunks::populateThunk(MachineFunction &MF,
+                                       Optional<unsigned> Reg) {
   // Set MF properties. We never use vregs...
   MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
 
-  BasicBlock &OrigEntryBB = F.getEntryBlock();
-  MachineBasicBlock *Entry = MF.CreateMachineBasicBlock(&OrigEntryBB);
-  MachineBasicBlock *CaptureSpec = MF.CreateMachineBasicBlock(&OrigEntryBB);
-  MachineBasicBlock *CallTarget = MF.CreateMachineBasicBlock(&OrigEntryBB);
+  MachineBasicBlock *Entry = &MF.front();
+  Entry->clear();
 
-  MF.push_back(Entry);
+  MachineBasicBlock *CaptureSpec = MF.CreateMachineBasicBlock(Entry->getBasicBlock());
+  MachineBasicBlock *CallTarget = MF.CreateMachineBasicBlock(Entry->getBasicBlock());
   MF.push_back(CaptureSpec);
   MF.push_back(CallTarget);
 

Modified: llvm/branches/release_50/test/CodeGen/X86/O0-pipeline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_50/test/CodeGen/X86/O0-pipeline.ll?rev=324009&r1=324008&r2=324009&view=diff
==============================================================================
--- llvm/branches/release_50/test/CodeGen/X86/O0-pipeline.ll (original)
+++ llvm/branches/release_50/test/CodeGen/X86/O0-pipeline.ll Thu Feb  1 13:31:35 2018
@@ -56,8 +56,7 @@
 ; CHECK-NEXT:       Machine Natural Loop Construction
 ; CHECK-NEXT:       Insert XRay ops
 ; CHECK-NEXT:       Implement the 'patchable-function' attribute
-; CHECK-NEXT:     X86 Retpoline Thunks
-; CHECK-NEXT:     FunctionPass Manager
+; CHECK-NEXT:       X86 Retpoline Thunks
 ; CHECK-NEXT:       Lazy Machine Block Frequency Analysis
 ; CHECK-NEXT:       Machine Optimization Remark Emitter
 ; CHECK-NEXT:       MachineDominator Tree Construction




More information about the llvm-branch-commits mailing list