[MachineOutliner] Add defs to calls + don't track liveness on outlined functions
authorJessica Paquette <jpaquette@apple.com>
Fri, 27 Apr 2018 23:36:35 +0000 (23:36 +0000)
committerJessica Paquette <jpaquette@apple.com>
Fri, 27 Apr 2018 23:36:35 +0000 (23:36 +0000)
This commit makes it so that if you outline a def of some register, then the
call instruction created by the outliner actually reflects that the register
is defined by the call. It also makes it so that outlined functions don't
have the TracksLiveness property.

Outlined calls shouldn't break liveness assumptions that someone might make.

This also un-XFAILs the noredzone test, and updates the calls test.

llvm-svn: 331095

llvm/lib/CodeGen/MachineOutliner.cpp
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/test/CodeGen/AArch64/machine-outliner-calls.mir
llvm/test/CodeGen/AArch64/machine-outliner-noredzone.ll

index d56f113..d0f6f56 100644 (file)
@@ -1323,6 +1323,8 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
     DB.finalize();
   }
 
+  // Outlined functions shouldn't preserve liveness.
+  MF.getProperties().reset(MachineFunctionProperties::Property::TracksLiveness);
   MF.getRegInfo().freezeReservedRegs(MF);
   return &MF;
 }
@@ -1357,8 +1359,6 @@ bool MachineOutliner::outline(
     MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
     assert(EndIt != MBB->end() && "EndIt out of bounds!");
 
-    EndIt++; // Erase needs one past the end index.
-
     // Does this candidate have a function yet?
     if (!OF.MF) {
       OF.MF = createOutlinedFunction(M, OF, Mapper);
@@ -1401,10 +1401,40 @@ bool MachineOutliner::outline(
     const TargetInstrInfo &TII = *STI.getInstrInfo();
 
     // Insert a call to the new function and erase the old sequence.
-    TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.MInfo);
+    auto CallInst = TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.MInfo);
     StartIt = Mapper.InstrList[C.getStartIdx()];
-    MBB->erase(StartIt, EndIt);
 
+    // If the caller tracks liveness, then we need to make sure that anything
+    // we outline doesn't break liveness assumptions.
+    // The outlined functions themselves currently don't track liveness, but
+    // we should make sure that the ranges we yank things out of aren't
+    // wrong.
+    if (MBB->getParent()->getProperties().hasProperty(
+            MachineFunctionProperties::Property::TracksLiveness)) {
+      // Helper lambda for adding implicit def operands to the call instruction.
+      auto CopyDefs = [&CallInst](MachineInstr &MI) {
+        for (MachineOperand &MOP : MI.operands()) {
+          // Skip over anything that isn't a register.
+          if (!MOP.isReg())
+            continue;
+
+          // If it's a def, add it to the call instruction.
+          if (MOP.isDef())
+            CallInst->addOperand(
+                MachineOperand::CreateReg(MOP.getReg(), true, /* isDef = true */
+                                          true /* isImp = true */));
+        }
+      };
+
+      // Copy over the defs in the outlined range.
+      // First inst in outlined range <-- Anything that's defined in this
+      // ...                           .. range has to be added as an implicit
+      // Last inst in outlined range  <-- def to the call instruction.
+      std::for_each(CallInst, EndIt, CopyDefs);
+    }
+
+    EndIt++; // Erase needs one past the end index.
+    MBB->erase(StartIt, EndIt);
     OutlinedSomething = true;
 
     // Statistics.
index ee81c16..53946ea 100644 (file)
@@ -5351,6 +5351,9 @@ MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall(
     return It;
   }
 
+  // We want to return the spot where we inserted the call.
+  MachineBasicBlock::iterator CallPt;
+
   // We have a default call. Save the link register.
   MachineInstr *STRXpre = BuildMI(MF, DebugLoc(), get(AArch64::STRXpre))
                               .addReg(AArch64::SP, RegState::Define)
@@ -5363,7 +5366,7 @@ MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall(
   // Insert the call.
   It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL))
                           .addGlobalAddress(M.getNamedValue(MF.getName())));
-
+  CallPt = It;
   It++;
 
   // Restore the link register.
@@ -5374,5 +5377,5 @@ MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall(
                                .addImm(16);
   It = MBB.insert(It, LDRXpost);
 
-  return It;
+  return CallPt;
 }
index 41010d8..00025ab 100644 (file)
@@ -56,7 +56,6 @@ body:             |
 
 # CHECK: name:            OUTLINED_FUNCTION_0
 # CHECK-DAG: bb.0:
-# CHECK-NEXT: liveins: $lr
 # CHECK-DAG: frame-setup CFI_INSTRUCTION def_cfa_offset -16
 # CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $w30, 16
 # CHECK-NEXT: early-clobber $sp = STRXpre $lr, $sp, -16
index e2c85e6..36d860a 100644 (file)
@@ -1,4 +1,3 @@
-; XFAIL: *
 ; RUN: llc -verify-machineinstrs -enable-machine-outliner %s -o - | FileCheck %s
 ; RUN: llc -verify-machineinstrs -enable-machine-outliner -aarch64-redzone %s -o - | FileCheck %s -check-prefix=REDZONE