-//===-- PPCBranchSelector.cpp - Emit long conditional branches-----*- C++ -*-=//
+//===-- PPCBranchSelector.cpp - Emit long conditional branches ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file contains a pass that scans a machine function to determine which
// conditional branches need more than 16 bits of displacement to reach their
// target basic block. It does this in two passes; a calculation of basic block
-// positions pass, and a branch psuedo op to machine branch opcode pass. This
+// positions pass, and a branch pseudo op to machine branch opcode pass. This
// pass should be run last, just before the assembly printer.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ppc-branch-select"
#include "PPC.h"
+#include "MCTargetDesc/PPCPredicates.h"
#include "PPCInstrBuilder.h"
#include "PPCInstrInfo.h"
-#include "PPCPredicates.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetMachine.h"
using namespace llvm;
STATISTIC(NumExpanded, "Number of branches expanded to long format");
+namespace llvm {
+ void initializePPCBSelPass(PassRegistry&);
+}
+
namespace {
- struct VISIBILITY_HIDDEN PPCBSel : public MachineFunctionPass {
+ struct PPCBSel : public MachineFunctionPass {
static char ID;
- PPCBSel() : MachineFunctionPass((intptr_t)&ID) {}
+ PPCBSel() : MachineFunctionPass(ID) {
+ initializePPCBSelPass(*PassRegistry::getPassRegistry());
+ }
/// BlockSizes - The sizes of the basic blocks in the function.
std::vector<unsigned> BlockSizes;
char PPCBSel::ID = 0;
}
+INITIALIZE_PASS(PPCBSel, "ppc-branch-select", "PowerPC Branch Selector",
+ false, false)
+
/// createPPCBranchSelectionPass - returns an instance of the Branch Selection
/// Pass
///
return new PPCBSel();
}
-/// getNumBytesForInstruction - Return the number of bytes of code the specified
-/// instruction may be. This returns the maximum number of bytes.
-///
-static unsigned getNumBytesForInstruction(MachineInstr *MI) {
- switch (MI->getOpcode()) {
- case PPC::INLINEASM: { // Inline Asm: Variable size.
- MachineFunction *MF = MI->getParent()->getParent();
- const char *AsmStr = MI->getOperand(0).getSymbolName();
- return MF->getTarget().getTargetAsmInfo()->getInlineAsmLength(AsmStr);
- }
- case PPC::LABEL: {
- return 0;
- }
- default:
- return 4; // PowerPC instructions are all 4 bytes
- }
-}
-
-
bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
- const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
+ const PPCInstrInfo *TII =
+ static_cast<const PPCInstrInfo*>(Fn.getTarget().getInstrInfo());
// Give the blocks of the function a dense, in-order, numbering.
Fn.RenumberBlocks();
BlockSizes.resize(Fn.getNumBlockIDs());
unsigned BlockSize = 0;
for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
MBBI != EE; ++MBBI)
- BlockSize += getNumBytesForInstruction(MBBI);
+ BlockSize += TII->GetInstSizeInBytes(MBBI);
BlockSizes[MBB->getNumber()] = BlockSize;
FuncSize += BlockSize;
unsigned MBBStartOffset = 0;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) {
- if (I->getOpcode() != PPC::BCC || I->getOperand(2).isImmediate()) {
- MBBStartOffset += getNumBytesForInstruction(I);
+ if (I->getOpcode() != PPC::BCC || I->getOperand(2).isImm()) {
+ MBBStartOffset += TII->GetInstSizeInBytes(I);
continue;
}
}
// If this branch is in range, ignore it.
- if (isInt16(BranchSize)) {
+ if (isInt<16>(BranchSize)) {
MBBStartOffset += 4;
continue;
}
-
+
// Otherwise, we have to expand it to a long branch.
- // The BCC operands are:
- // 0. PPC branch predicate
- // 1. CR register
- // 2. Target MBB
- PPC::Predicate Pred = (PPC::Predicate)I->getOperand(0).getImm();
- unsigned CRReg = I->getOperand(1).getReg();
-
MachineInstr *OldBranch = I;
-
- // Jump over the uncond branch inst (i.e. $PC+8) on opposite condition.
- BuildMI(MBB, I, TII->get(PPC::BCC))
- .addImm(PPC::InvertPredicate(Pred)).addReg(CRReg).addImm(2);
+ DebugLoc dl = OldBranch->getDebugLoc();
+
+ if (I->getOpcode() == PPC::BCC) {
+ // The BCC operands are:
+ // 0. PPC branch predicate
+ // 1. CR register
+ // 2. Target MBB
+ PPC::Predicate Pred = (PPC::Predicate)I->getOperand(0).getImm();
+ unsigned CRReg = I->getOperand(1).getReg();
+
+ // Jump over the uncond branch inst (i.e. $PC+8) on opposite condition.
+ BuildMI(MBB, I, dl, TII->get(PPC::BCC))
+ .addImm(PPC::InvertPredicate(Pred)).addReg(CRReg).addImm(2);
+ } else if (I->getOpcode() == PPC::BDNZ) {
+ BuildMI(MBB, I, dl, TII->get(PPC::BDZ)).addImm(2);
+ } else if (I->getOpcode() == PPC::BDNZ8) {
+ BuildMI(MBB, I, dl, TII->get(PPC::BDZ8)).addImm(2);
+ } else if (I->getOpcode() == PPC::BDZ) {
+ BuildMI(MBB, I, dl, TII->get(PPC::BDNZ)).addImm(2);
+ } else if (I->getOpcode() == PPC::BDZ8) {
+ BuildMI(MBB, I, dl, TII->get(PPC::BDNZ8)).addImm(2);
+ } else {
+ llvm_unreachable("Unhandled branch type!");
+ }
// Uncond branch to the real destination.
- I = BuildMI(MBB, I, TII->get(PPC::B)).addMBB(Dest);
+ I = BuildMI(MBB, I, dl, TII->get(PPC::B)).addMBB(Dest);
// Remove the old branch from the function.
OldBranch->eraseFromParent();