48#define DEBUG_TYPE "hexmux"
62 "farther of the two predicated uses"));
73 return "Hexagon generate mux instructions";
84 MachineFunctionProperties::Property::NoVRegs);
93 unsigned TrueX = std::numeric_limits<unsigned>::max();
94 unsigned FalseX = std::numeric_limits<unsigned>::max();
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);
127 void getSubRegs(
unsigned Reg,
BitVector &SRs)
const;
128 void expandReg(
unsigned Reg,
BitVector &Set)
const;
133 bool isCondTransfer(
unsigned Opc)
const;
141char HexagonGenMux::ID = 0;
144 "Hexagon generate mux instructions",
false,
false)
146void HexagonGenMux::getSubRegs(
unsigned Reg,
BitVector &SRs)
const {
151void HexagonGenMux::expandReg(
unsigned Reg,
BitVector &Set)
const {
153 getSubRegs(Reg, Set);
161 unsigned Opc =
MI->getOpcode();
170 if (!MO.isReg() || MO.isImplicit())
179 DefUseInfoMap &DUM) {
181 unsigned NR = HRI->getNumRegs();
185 I2X.insert(std::make_pair(&
MI,
Index));
188 getDefsUses(&
MI, Defs,
Uses);
189 DUM.insert(std::make_pair(
Index, DefUseInfo(Defs,
Uses)));
194bool HexagonGenMux::isCondTransfer(
unsigned Opc)
const {
196 case Hexagon::A2_tfrt:
197 case Hexagon::A2_tfrf:
198 case Hexagon::C2_cmoveit:
199 case Hexagon::C2_cmoveif:
207 bool IsReg1 = Src1.
isReg(), IsReg2 = Src2.
isReg();
209 return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir;
211 return Hexagon::C2_muxri;
216 return Hexagon::C2_muxii;
222 bool Changed =
false;
225 buildMaps(
B, I2X, DUM);
233 unsigned Opc =
MI.getOpcode();
234 if (!isCondTransfer(Opc))
244 unsigned Idx = I2X.lookup(&
MI);
245 CondsetMap::iterator
F = CM.find(DR);
246 bool IfTrue = HII->isPredicatedTrue(Opc);
250 if (
F != CM.end() &&
F->second.PredR != PR) {
255 auto It = CM.insert(std::make_pair(DR, CondsetInfo()));
257 F->second.PredR = PR;
259 CondsetInfo &CI =
F->second;
264 if (CI.TrueX == std::numeric_limits<unsigned>::max() ||
265 CI.FalseX == std::numeric_limits<unsigned>::max())
273 unsigned MinX = std::min(CI.TrueX, CI.FalseX);
274 unsigned MaxX = std::max(CI.TrueX, CI.FalseX);
278 bool NearDef =
false;
279 for (
unsigned X = SearchX;
X < MaxX; ++
X) {
280 const DefUseInfo &DU = DUM.lookup(
X);
296 std::advance(It1, MinX);
297 std::advance(It2, MaxX);
302 bool Failure =
false, CanUp =
true, CanDown =
true;
303 for (
unsigned X = MinX+1;
X < MaxX;
X++) {
304 const DefUseInfo &DU = DUM.lookup(
X);
305 if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) {
309 if (CanDown && DU.Defs[SR1])
311 if (CanUp && DU.Defs[SR2])
314 if (Failure || (!CanUp && !CanDown))
322 ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2));
325 for (MuxInfo &MX :
ML) {
326 unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF);
332 if (!MX.At->getParent() || !MX.Def1->getParent() || !MX.Def2->getParent())
337 auto NewMux =
BuildMI(
B, MX.At,
DL, HII->get(MxOpc), MX.DefR)
352 if (
I.isDebugInstr())
359 if (!
Op.isReg() || !
Op.isUse())
361 assert(
Op.getSubReg() == 0 &&
"Should have physical registers only");
362 bool Live = !LPR.available(
Op.getReg());
376 bool Changed =
false;
378 Changed |= genMuxInBlock(
I);
383 return new HexagonGenMux();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Looks at all the uses of the given value Returns the Liveness deduced from the uses of this value Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses If the result is Live
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Rewrite Partial Register Uses
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"))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
A set of register units used to track register liveness.
Describe properties that are true of each instruction in the target description file.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
const MachineOperand & getOperand(unsigned i) const
void clearKillInfo()
Clears kill flags on all operands.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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...
auto reverse(ContainerTy &&C)
FunctionPass * createHexagonGenMux()
void initializeHexagonGenMuxPass(PassRegistry &Registry)