diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
| commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
| tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /lib/Target/PowerPC/PPCBranchSelector.cpp | |
| parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) | |
Notes
Diffstat (limited to 'lib/Target/PowerPC/PPCBranchSelector.cpp')
| -rw-r--r-- | lib/Target/PowerPC/PPCBranchSelector.cpp | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/lib/Target/PowerPC/PPCBranchSelector.cpp b/lib/Target/PowerPC/PPCBranchSelector.cpp index 4d63c5b5703c..ae76386fdfb6 100644 --- a/lib/Target/PowerPC/PPCBranchSelector.cpp +++ b/lib/Target/PowerPC/PPCBranchSelector.cpp @@ -19,8 +19,10 @@ #include "MCTargetDesc/PPCPredicates.h" #include "PPCInstrBuilder.h" #include "PPCInstrInfo.h" +#include "PPCSubtarget.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtargetInfo.h" @@ -41,19 +43,19 @@ namespace { initializePPCBSelPass(*PassRegistry::getPassRegistry()); } - /// BlockSizes - The sizes of the basic blocks in the function. - std::vector<unsigned> BlockSizes; + // The sizes of the basic blocks in the function (the first + // element of the pair); the second element of the pair is the amount of the + // size that is due to potential padding. + std::vector<std::pair<unsigned, unsigned>> BlockSizes; bool runOnMachineFunction(MachineFunction &Fn) override; MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( - MachineFunctionProperties::Property::AllVRegsAllocated); + MachineFunctionProperties::Property::NoVRegs); } - const char *getPassName() const override { - return "PowerPC Branch Selector"; - } + StringRef getPassName() const override { return "PowerPC Branch Selector"; } }; char PPCBSel::ID = 0; } @@ -92,8 +94,19 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) { return AlignAmt + OffsetToAlignment(Offset, AlignAmt); }; + // We need to be careful about the offset of the first block in the function + // because it might not have the function's alignment. This happens because, + // under the ELFv2 ABI, for functions which require a TOC pointer, we add a + // two-instruction sequence to the start of the function. + // Note: This needs to be synchronized with the check in + // PPCLinuxAsmPrinter::EmitFunctionBodyStart. + unsigned InitialOffset = 0; + if (Fn.getSubtarget<PPCSubtarget>().isELFv2ABI() && + !Fn.getRegInfo().use_empty(PPC::X2)) + InitialOffset = 8; + // Measure each MBB and compute a size for the entire function. - unsigned FuncSize = 0; + unsigned FuncSize = InitialOffset; for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ++MFI) { MachineBasicBlock *MBB = &*MFI; @@ -102,15 +115,19 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) { // alignment requirement. if (MBB->getNumber() > 0) { unsigned AlignExtra = GetAlignmentAdjustment(*MBB, FuncSize); - BlockSizes[MBB->getNumber()-1] += AlignExtra; + + auto &BS = BlockSizes[MBB->getNumber()-1]; + BS.first += AlignExtra; + BS.second = AlignExtra; + FuncSize += AlignExtra; } unsigned BlockSize = 0; for (MachineInstr &MI : *MBB) - BlockSize += TII->GetInstSizeInBytes(MI); + BlockSize += TII->getInstSizeInBytes(MI); - BlockSizes[MBB->getNumber()] = BlockSize; + BlockSizes[MBB->getNumber()].first = BlockSize; FuncSize += BlockSize; } @@ -155,7 +172,7 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) { Dest = I->getOperand(0).getMBB(); if (!Dest) { - MBBStartOffset += TII->GetInstSizeInBytes(*I); + MBBStartOffset += TII->getInstSizeInBytes(*I); continue; } @@ -169,14 +186,14 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) { BranchSize = MBBStartOffset; for (unsigned i = Dest->getNumber(), e = MBB.getNumber(); i != e; ++i) - BranchSize += BlockSizes[i]; + BranchSize += BlockSizes[i].first; } else { // Otherwise, add the size of the blocks between this block and the // dest to the number of bytes left in this block. BranchSize = -MBBStartOffset; for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i) - BranchSize += BlockSizes[i]; + BranchSize += BlockSizes[i].first; } // If this branch is in range, ignore it. @@ -186,9 +203,9 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) { } // Otherwise, we have to expand it to a long branch. - MachineInstr *OldBranch = I; - DebugLoc dl = OldBranch->getDebugLoc(); - + MachineInstr &OldBranch = *I; + DebugLoc dl = OldBranch.getDebugLoc(); + if (I->getOpcode() == PPC::BCC) { // The BCC operands are: // 0. PPC branch predicate @@ -222,16 +239,42 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) { I = BuildMI(MBB, I, dl, TII->get(PPC::B)).addMBB(Dest); // Remove the old branch from the function. - OldBranch->eraseFromParent(); - + OldBranch.eraseFromParent(); + // Remember that this instruction is 8-bytes, increase the size of the // block by 4, remember to iterate. - BlockSizes[MBB.getNumber()] += 4; + BlockSizes[MBB.getNumber()].first += 4; MBBStartOffset += 8; ++NumExpanded; MadeChange = true; } } + + if (MadeChange) { + // If we're going to iterate again, make sure we've updated our + // padding-based contributions to the block sizes. + unsigned Offset = InitialOffset; + for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; + ++MFI) { + MachineBasicBlock *MBB = &*MFI; + + if (MBB->getNumber() > 0) { + auto &BS = BlockSizes[MBB->getNumber()-1]; + BS.first -= BS.second; + Offset -= BS.second; + + unsigned AlignExtra = GetAlignmentAdjustment(*MBB, Offset); + + BS.first += AlignExtra; + BS.second = AlignExtra; + + Offset += AlignExtra; + } + + Offset += BlockSizes[MBB->getNumber()].first; + } + } + EverMadeChange |= MadeChange; } |
