Index: llvm/lib/CodeGen/MachineOutliner.cpp =================================================================== --- llvm/lib/CodeGen/MachineOutliner.cpp +++ llvm/lib/CodeGen/MachineOutliner.cpp @@ -1163,12 +1163,13 @@ for (auto I = FirstCand.front(), E = std::next(FirstCand.back()); I != E; ++I) { MachineInstr *NewMI = MF.CloneMachineInstr(&*I); - if(I->isCFIInstruction()){ + if (I->isCFIInstruction()) { MachineFunction *OriginalMF = I->getMF(); const std::vector &Instrs = - OriginalMF->getFrameInstructions(); - for(MCCFIInstruction CFI : Instrs) - (void)MF.addFrameInst(CFI); + OriginalMF->getFrameInstructions(); + unsigned CFIIndex = NewMI->getOperand(0).getCFIIndex(); + MCCFIInstruction CFI = Instrs[CFIIndex]; + (void)MF.addFrameInst(CFI); } NewMI->dropMemRefs(MF); @@ -1218,8 +1219,6 @@ return &MF; } -InstructionMapper Mapper; - bool MachineOutliner::outline(Module &M, std::vector &FunctionList, InstructionMapper &Mapper, @@ -1340,7 +1339,6 @@ } LLVM_DEBUG(dbgs() << "OutlinedSomething = " << OutlinedSomething << "\n";); - return OutlinedSomething; } Index: llvm/lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -24,9 +24,9 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/StackMaps.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -47,7 +47,9 @@ #include #include #include +#include #include +#include using namespace llvm; @@ -5862,14 +5864,31 @@ return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement"); }); - bool HasCFI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) { - for (MachineBasicBlock::iterator mit : *(C.getMBB())) { - if (mit->isCFIInstruction()) { - return true; - } + std::vector CFIInstructions = + RepeatedSequenceLocs[0].getMF()->getFrameInstructions(); + std::vector CFIInstructionsPresent; + + // We check to see if CFI Instructions are present, and if they are + // we add it to a vector + bool HasCFI = false; + MachineBasicBlock::iterator Mit = RepeatedSequenceLocs[0].front(); + for (unsigned Loc = RepeatedSequenceLocs[0].getStartIdx(); + Loc < RepeatedSequenceLocs[0].getEndIdx() + 1; Loc++) { + if (Mit->isCFIInstruction()) { + HasCFI = true; + unsigned CFIIndex = Mit->getOperand(0).getCFIIndex(); + MCCFIInstruction CFI = CFIInstructions[CFIIndex]; + CFIInstructionsPresent.push_back(CFI); } - return false; - }); + Mit++; + } + + // Since each set of instructions is a substring, if there are CFI + // Instructions and size matches, we know that we have captured all the + // CFI instruction, so it will be safe to outline. If it is not, we do not + // return the candidate + if (HasCFI && CFIInstructionsPresent.size() != CFIInstructions.size()) + return outliner::OutlinedFunction(); // Returns true if an instructions is safe to fix up, false otherwise. auto IsSafeToFixup = [this, &TRI](MachineInstr &MI) { @@ -6046,6 +6065,8 @@ } } + // If we have CFI instructions, we can only outline if the outlined section + // can be a tail call if (FrameID != MachineOutlinerTailCall && HasCFI) return outliner::OutlinedFunction(); @@ -6170,9 +6191,9 @@ if (FuncInfo->getLOHRelated().count(&MI)) return outliner::InstrType::Illegal; - // We can only outline these if we will tail call the outlined function, or - // fix up the CFI offsets. For the sake of safety, don't outline CFI - // instructions. + // We only outline these if we will tail call the outlined function, or + // fix up the CFI offsets. CFI instructions are outlined only if in a tail + // call. // // FIXME: If the proper fixups are implemented, this should be possible. if (MI.isCFIInstruction()) Index: llvm/lib/Target/X86/X86InstrInfo.cpp =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.cpp +++ llvm/lib/Target/X86/X86InstrInfo.cpp @@ -8682,6 +8682,32 @@ return Sum + 1; }); + std::vector CFIInstructions = + RepeatedSequenceLocs[0].getMF()->getFrameInstructions(); + std::vector CFIInstructionsPresent; + + // We check to see if CFI Instructions are present, and if they are + // we add it to a vector + bool HasCFI = false; + MachineBasicBlock::iterator Mit = RepeatedSequenceLocs[0].front(); + for (unsigned Loc = RepeatedSequenceLocs[0].getStartIdx(); + Loc < RepeatedSequenceLocs[0].getEndIdx() + 1; Loc++) { + if (Mit->isCFIInstruction()) { + HasCFI = true; + unsigned CFIIndex = Mit->getOperand(0).getCFIIndex(); + MCCFIInstruction CFI = CFIInstructions[CFIIndex]; + CFIInstructionsPresent.push_back(CFI); + } + Mit++; + } + + // Since each set of instructions is a substring, if there are CFI + // Instructions and size matches, we know that we have captured all the + // CFI instruction, so it will be safe to outline. If it is not, we do not + // return the candidate + if (HasCFI && CFIInstructionsPresent.size() != CFIInstructions.size()) + return outliner::OutlinedFunction(); + // FIXME: Use real size in bytes for call and ret instructions. if (RepeatedSequenceLocs[0].back()->isTerminator()) { for (outliner::Candidate &C : RepeatedSequenceLocs) @@ -8693,15 +8719,7 @@ ); } - bool hasCFI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) { - for (MachineBasicBlock::iterator mit = C.front();mit != C.back();mit++){ - if (mit->isCFIInstruction()) - return true; - } - return false; - }); - - if (hasCFI) + if (HasCFI) return outliner::OutlinedFunction(); for (outliner::Candidate &C : RepeatedSequenceLocs) Index: llvm/test/CodeGen/AArch64/machine-outliner-cfi-tail.mir =================================================================== --- llvm/test/CodeGen/AArch64/machine-outliner-cfi-tail.mir +++ llvm/test/CodeGen/AArch64/machine-outliner-cfi-tail.mir @@ -2,8 +2,8 @@ # RUN: llc -mtriple=aarch64-apple-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s # Outlining CFI instructions is unsafe if it is not tail called, but otherwise, -# it requires fixups. Show that we don't include CFI instructions in non -# tail call outlined sequences right now. +# it requires fixups. Show that we include CFI instructions in tail call +# outlined sequences right now. --- | define void @foo() #0 { ret void }