diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index a64295cf82064d..ef6069255dfb7b 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -941,13 +941,12 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M, MachineModuleInfo &MMI) { // Build instruction mappings for each function in the module. Start by // iterating over each Function in M. + LLVM_DEBUG(dbgs() << "*** Populating mapper ***\n"); for (Function &F : M) { + LLVM_DEBUG(dbgs() << "MAPPING FUNCTION: " << F.getName() << "\n"); if (F.hasFnAttribute("nooutline")) { - LLVM_DEBUG({ - dbgs() << "... Skipping function with nooutline attribute: " - << F.getName() << "\n"; - }); + LLVM_DEBUG(dbgs() << "SKIP: Function has nooutline attribute\n"); continue; } @@ -957,36 +956,51 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M, // If it doesn't, then there's nothing to outline from. Move to the next // Function. - if (!MF) + if (!MF) { + LLVM_DEBUG(dbgs() << "SKIP: Function does not have a MachineFunction\n"); continue; + } const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); - - if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault(*MF)) + if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault(*MF)) { + LLVM_DEBUG(dbgs() << "SKIP: Target does not want to outline from " + "function by default\n"); continue; + } // We have a MachineFunction. Ask the target if it's suitable for outlining. // If it isn't, then move on to the next Function in the module. - if (!TII->isFunctionSafeToOutlineFrom(*MF, OutlineFromLinkOnceODRs)) + if (!TII->isFunctionSafeToOutlineFrom(*MF, OutlineFromLinkOnceODRs)) { + LLVM_DEBUG(dbgs() << "SKIP: " << MF->getName() + << ": unsafe to outline from\n"); continue; + } // We have a function suitable for outlining. Iterate over every // MachineBasicBlock in MF and try to map its instructions to a list of // unsigned integers. + const unsigned MinMBBSize = 2; + for (MachineBasicBlock &MBB : *MF) { + LLVM_DEBUG(dbgs() << " MAPPING MBB: '" << MBB.getName() << "'\n"); // If there isn't anything in MBB, then there's no point in outlining from // it. // If there are fewer than 2 instructions in the MBB, then it can't ever // contain something worth outlining. // FIXME: This should be based off of the maximum size in B of an outlined // call versus the size in B of the MBB. - if (MBB.size() < 2) + if (MBB.size() < MinMBBSize) { + LLVM_DEBUG(dbgs() << " SKIP: MBB size less than minimum size of " + << MinMBBSize << "\n"); continue; + } // Check if MBB could be the target of an indirect branch. If it is, then // we don't want to outline from it. - if (MBB.hasAddressTaken()) + if (MBB.hasAddressTaken()) { + LLVM_DEBUG(dbgs() << " SKIP: MBB's address is taken\n"); continue; + } // MBB is suitable for outlining. Map it to a list of unsigneds. Mapper.convertToUnsignedVec(MBB, *TII); diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-mapper-debug-output.mir b/llvm/test/CodeGen/AArch64/machine-outliner-mapper-debug-output.mir new file mode 100644 index 00000000000000..826157e68d75c7 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-mapper-debug-output.mir @@ -0,0 +1,58 @@ +# RUN: llc -mtriple=aarch64 -debug-only=machine-outliner -run-pass=machine-outliner -verify-machineinstrs %s -o /dev/null 2>&1 | FileCheck %s +# REQUIRES: asserts + +# CHECK-LABEL: *** Populating mapper *** +# CHECK-NEXT: MAPPING FUNCTION: block_too_small +# CHECK-NEXT: MAPPING MBB: '' +# CHECK-NEXT: SKIP: MBB size less than minimum size of 2 +# CHECK-NEXT: MAPPING FUNCTION: no_outline +# CHECK-NEXT: SKIP: Function has nooutline attribute +# CHECK-NEXT: MAPPING FUNCTION: redzone +# CHECK-NEXT: SKIP: redzone: unsafe to outline from +# CHECK-NEXT: MAPPING FUNCTION: no_mf +# CHECK-NEXT: SKIP: Function does not have a MachineFunction +# CHECK-NEXT: MAPPING FUNCTION: block_addr_fn +# CHECK-NEXT: MAPPING MBB: 'label' +# CHECK-NEXT: SKIP: MBB's address is taken + +--- | + define void @block_too_small() noredzone { unreachable } + define void @no_outline() noredzone "nooutline" { unreachable } + define void @redzone() { unreachable } + declare void @no_mf() + define void @block_addr_fn() noredzone { + entry: + br label %label + label: + call void @block_addr_fn(ptr blockaddress(@block_addr_fn, %label)) + ret void + } +... +--- +name: no_outline +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $lr, $w8 + RET undef $lr +... +--- +name: block_too_small +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $lr, $w8 + RET undef $lr +... +--- +name: block_addr_fn +tracksRegLiveness: true +body: | + bb.0.label (ir-block-address-taken %ir-block.label): + liveins: $w0, $lr, $w8 + $w0 = ORRWri $wzr, 1 + $w0 = ORRWri $wzr, 1 + $w0 = ORRWri $wzr, 4 + RET undef $lr +... +--- diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-nooutline-attribute.mir b/llvm/test/CodeGen/AArch64/machine-outliner-nooutline-attribute.mir deleted file mode 100644 index 477a16c8413300..00000000000000 --- a/llvm/test/CodeGen/AArch64/machine-outliner-nooutline-attribute.mir +++ /dev/null @@ -1,42 +0,0 @@ -# RUN: llc -mtriple=aarch64 -debug-only=machine-outliner -run-pass=machine-outliner -verify-machineinstrs %s -o - 2>&1 | FileCheck %s -# REQUIRES: asserts - -# CHECK: ... Skipping function with nooutline attribute: no_outline -# CHECK-NOT: ... Skipping function with nooutline attribute: baz -# CHECK-NOT: OUTLINED - ---- | - define void @no_outline() #0 { unreachable } - define void @baz() { unreachable } - attributes #0 = { noredzone "nooutline" } -... ---- - -name: no_outline -tracksRegLiveness: true -body: | - bb.0: - liveins: $w0, $lr, $w8 - $sp = frame-setup SUBXri $sp, 32, 0 - $fp = frame-setup ADDXri $sp, 16, 0 - bb.1: - BL @baz, implicit-def dead $lr, implicit $sp - $w17 = ORRWri $wzr, 1 - $w17 = ORRWri $wzr, 1 - $w0 = ORRWri $wzr, 4 - BL @baz, implicit-def dead $lr, implicit $sp - $w17 = ORRWri $wzr, 1 - $w17 = ORRWri $wzr, 1 - $w0 = ORRWri $wzr, 3 - BL @baz, implicit-def dead $lr, implicit $sp - $w17 = ORRWri $wzr, 1 - $w17 = ORRWri $wzr, 1 - $w0 = ORRWri $wzr, 2 - BL @baz, implicit-def dead $lr, implicit $sp - $w17 = ORRWri $wzr, 1 - $w17 = ORRWri $wzr, 1 - $w0 = ORRWri $wzr, 1 - bb.2: - $fp, $lr = LDPXi $sp, 2 - RET undef $lr -