LLVM
8.0.1
|
This pass do two things: More...
#include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsMCNaCl.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
#include "MipsSubtarget.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <utility>
Go to the source code of this file.
Macros | |
#define | DEBUG_TYPE "mips-branch-expansion" |
Functions | |
STATISTIC (NumInsertedNops, "Number of nops inserted") | |
STATISTIC (LongBranches, "Number of long branches.") | |
INITIALIZE_PASS (MipsBranchExpansion, DEBUG_TYPE, "Expand out of range branch instructions and fix forbidden" " slot hazards", false, false) FunctionPass *llvm | |
Returns a pass that clears pipeline hazards. More... | |
static Iter | getNextMachineInstrInBB (Iter Position) |
static std::pair< Iter, bool > | getNextMachineInstr (Iter Position, MachineBasicBlock *Parent) |
static MachineBasicBlock * | getTargetMBB (const MachineInstr &Br) |
Iterate over list of Br's operands and search for a MachineBasicBlock operand. More... | |
static ReverseIter | getNonDebugInstr (ReverseIter B, const ReverseIter &E) |
static void | emitGPDisp (MachineFunction &F, const MipsInstrInfo *TII) |
Variables | |
static cl::opt< bool > | SkipLongBranch ("skip-mips-long-branch", cl::init(false), cl::desc("MIPS: Skip branch expansion pass."), cl::Hidden) |
static cl::opt< bool > | ForceLongBranch ("force-mips-long-branch", cl::init(false), cl::desc("MIPS: Expand all branches to long format."), cl::Hidden) |
This pass do two things:
The reason why this pass combines these two tasks is that one of these two tasks can break the result of the previous one.
Example of that is a situation where at first, no branch should be expanded, but after adding at least one nop somewhere in the code to prevent a forbidden slot hazard, offset of some branches may go out of range. In that case it is necessary to check again if there is some branch that needs expansion. On the other hand, expanding some branch may cause a control transfer instruction to appear in the forbidden slot, which is a hazard that should be fixed. This pass alternates between this two tasks untill no changes are made. Only then we can be sure that all branches are expanded properly, and no hazard situations exist.
Regarding branch expanding:
When branch instruction like beqzc or bnezc has offset that is too large to fit into its immediate field, it has to be expanded to another instruction or series of instructions.
FIXME: Fix pc-region jump instructions which cross 256MB segment boundaries. TODO: Handle out of range bc, b (pseudo) instructions.
Regarding compact branch hazard prevention:
Hazards handled: forbidden slots for MIPSR6.
A forbidden slot hazard occurs when a compact branch instruction is executed and the adjacent instruction in memory is a control transfer instruction such as a branch or jump, ERET, ERETNC, DERET, WAIT and PAUSE.
For example:
0x8004 bnec a1,v0,<P+0x18> 0x8008 beqc a1,a2,<P+0x54>
In such cases, the processor is required to signal a Reserved Instruction exception.
Here, if the instruction at 0x8004 is executed, the processor will raise an exception as there is a control transfer instruction at 0x8008.
There are two sources of forbidden slot hazards:
A) A previous pass has created a compact branch directly. B) Transforming a delay slot branch into compact branch. This case can be difficult to process as lookahead for hazards is insufficient, as backwards delay slot fillling can also produce hazards in previously processed instuctions.
In future this pass can be extended (or new pass can be created) to handle other pipeline hazards, such as various MIPS1 hazards, processor errata that require instruction reorganization, etc.
This pass has to run after the delay slot filler as that pass can introduce pipeline hazards such as compact branch hazard, hence the existing hazard recognizer is not suitable.
Definition in file MipsBranchExpansion.cpp.
#define DEBUG_TYPE "mips-branch-expansion" |
Definition at line 108 of file MipsBranchExpansion.cpp.
|
static |
Definition at line 721 of file MipsBranchExpansion.cpp.
References llvm::MachineInstrBuilder::addExternalSymbol(), llvm::MIBundleBuilder::append(), llvm::MachineBasicBlock::begin(), llvm::BuildMI(), E, llvm::MachineBasicBlock::findDebugLoc(), llvm::MachineFunction::front(), getNextMachineInstr(), I, llvm::MipsII::MO_ABS_HI, llvm::MipsII::MO_ABS_LO, llvm::MachineBasicBlock::removeLiveIn(), SkipLongBranch, and TII.
|
static |
Definition at line 203 of file MipsBranchExpansion.cpp.
References llvm::MachineBasicBlock::begin(), llvm::MachineBasicBlock::empty(), llvm::MachineBasicBlock::end(), getNextMachineInstrInBB(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getNextNode(), and llvm::MachineBasicBlock::isSuccessor().
Referenced by emitGPDisp().
|
static |
Definition at line 193 of file MipsBranchExpansion.cpp.
References E, llvm::find_if_not(), and I.
Referenced by getNextMachineInstr().
|
static |
Definition at line 239 of file MipsBranchExpansion.cpp.
References B, E, and splitMBB().
|
static |
Iterate over list of Br's operands and search for a MachineBasicBlock operand.
Definition at line 226 of file MipsBranchExpansion.cpp.
References E, llvm::MachineInstr::getDesc(), llvm::MachineOperand::getMBB(), llvm::MCInstrDesc::getNumOperands(), llvm::MachineInstr::getOperand(), I, llvm::MachineOperand::isMBB(), and llvm_unreachable.
INITIALIZE_PASS | ( | MipsBranchExpansion | , |
DEBUG_TYPE | , | ||
"Expand out of range branch instructions and fix forbidden" " slot hazards" | , | ||
false | , | ||
false | |||
) |
Returns a pass that clears pipeline hazards.
Definition at line 181 of file MipsBranchExpansion.cpp.
STATISTIC | ( | NumInsertedNops | , |
"Number of nops inserted" | |||
) |
STATISTIC | ( | LongBranches | , |
"Number of long branches." | |||
) |
|
static |
|
static |
Referenced by emitGPDisp().