Go to the documentation of this file.
48 #define DEBUG_TYPE "hexmux"
62 "farther of the two predicated uses"));
73 return "Hexagon generate mux instructions";
96 CondsetInfo() =
default;
102 DefUseInfo() =
default;
108 unsigned DefR, PredR;
115 : At(It), DefR(DR), PredR(PR), SrcT(TOp), SrcF(FOp), Def1(&D1),
123 bool isRegPair(
unsigned Reg)
const {
124 return Hexagon::DoubleRegsRegClass.contains(
Reg);
133 bool isCondTransfer(
unsigned Opc)
const;
144 "Hexagon generate mux instructions",
false,
false)
146 void HexagonGenMux::getSubRegs(
unsigned Reg,
BitVector &SRs)
const {
151 void HexagonGenMux::expandReg(
unsigned Reg,
BitVector &Set)
const {
153 getSubRegs(
Reg, Set);
161 unsigned Opc =
MI->getOpcode();
165 expandReg(*R++, Defs);
168 expandReg(*R++,
Uses);
172 if (!MO.isReg() || MO.isImplicit())
181 DefUseInfoMap &DUM) {
183 unsigned NR = HRI->getNumRegs();
187 I2X.insert(std::make_pair(&
MI,
Index));
190 getDefsUses(&
MI, Defs,
Uses);
191 DUM.insert(std::make_pair(
Index, DefUseInfo(Defs,
Uses)));
196 bool HexagonGenMux::isCondTransfer(
unsigned Opc)
const {
198 case Hexagon::A2_tfrt:
199 case Hexagon::A2_tfrf:
200 case Hexagon::C2_cmoveit:
201 case Hexagon::C2_cmoveif:
209 bool IsReg1 = Src1.
isReg(), IsReg2 = Src2.
isReg();
211 return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir;
213 return Hexagon::C2_muxri;
218 return Hexagon::C2_muxii;
224 bool Changed =
false;
227 buildMaps(
B, I2X, DUM);
235 unsigned Opc =
MI.getOpcode();
236 if (!isCondTransfer(Opc))
246 unsigned Idx = I2X.lookup(&
MI);
247 CondsetMap::iterator
F = CM.find(DR);
248 bool IfTrue = HII->isPredicatedTrue(Opc);
252 if (
F != CM.end() &&
F->second.PredR != PR) {
257 auto It = CM.insert(std::make_pair(DR, CondsetInfo()));
259 F->second.PredR = PR;
261 CondsetInfo &CI =
F->second;
275 unsigned MinX =
std::min(CI.TrueX, CI.FalseX);
276 unsigned MaxX =
std::max(CI.TrueX, CI.FalseX);
280 bool NearDef =
false;
281 for (
unsigned X = SearchX;
X < MaxX; ++
X) {
282 const DefUseInfo &DU = DUM.lookup(
X);
298 std::advance(It1, MinX);
299 std::advance(It2, MaxX);
304 bool Failure =
false, CanUp =
true, CanDown =
true;
305 for (
unsigned X = MinX+1;
X < MaxX;
X++) {
306 const DefUseInfo &DU = DUM.lookup(
X);
307 if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) {
311 if (CanDown && DU.Defs[SR1])
313 if (CanUp && DU.Defs[SR2])
316 if (Failure || (!CanUp && !CanDown))
324 ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2));
327 for (MuxInfo &MX : ML) {
328 unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF);
334 if (!MX.At->getParent() || !MX.Def1->getParent() || !MX.Def2->getParent())
339 auto NewMux =
BuildMI(
B, MX.At,
DL, HII->get(MxOpc), MX.DefR)
353 auto IsLive = [&LPR,
this] (
unsigned Reg) ->
bool {
355 if (LPR.contains(*
S))
360 if (
I.isDebugInstr())
367 if (!
Op.isReg() || !
Op.isUse())
369 assert(
Op.getSubReg() == 0 &&
"Should have physical registers only");
370 bool Live = IsLive(
Op.getReg());
384 bool Changed =
false;
386 Changed |= genMuxInBlock(
I);
391 return new HexagonGenMux();
This is an optimization pass for GlobalISel generic memory operations.
const MachineInstrBuilder & add(const MachineOperand &MO) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Reg
All possible values of the reg field in the ModR/M byte.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
A set of physical registers with utility functions to track liveness when walking backward/forward th...
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Properties which a MachineFunction may have at a given point in time.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
SmallPtrSet< MachineInstr *, 2 > Uses
FunctionPass * createHexagonGenMux()
const MachineOperand & getOperand(unsigned i) const
void clearKillInfo()
Clears kill flags on all operands.
Represent the analysis usage information of a pass.
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
MachineFunctionProperties & set(Property P)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
constexpr bool isInt< 8 >(int64_t x)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
INITIALIZE_PASS(HexagonGenMux, "hexagon-gen-mux", "Hexagon generate mux instructions", false, false) void HexagonGenMux
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
initializer< Ty > init(const Ty &Val)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
static cl::opt< unsigned > MinPredDist("hexagon-gen-mux-threshold", cl::Hidden, cl::init(0), cl::desc("Minimum distance between predicate definition and " "farther of the two predicated uses"))
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
StringRef - Represent a constant reference to a string, i.e.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Wrapper class representing virtual and physical registers.
Function & getFunction()
Return the LLVM function that this machine code represents.
void initializeHexagonGenMuxPass(PassRegistry &Registry)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MCSubRegIterator enumerates all sub-registers of Reg.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass class - This class is used to implement most global optimizations.