47#define DEBUG_TYPE "hexmux"
61 "farther of the two predicated uses"));
72 return "Hexagon generate mux instructions";
83 MachineFunctionProperties::Property::NoVRegs);
92 unsigned TrueX = std::numeric_limits<unsigned>::max();
93 unsigned FalseX = std::numeric_limits<unsigned>::max();
95 CondsetInfo() =
default;
101 DefUseInfo() =
default;
107 unsigned DefR, PredR;
114 : At(It), DefR(DR), PredR(PR), SrcT(TOp), SrcF(FOp), Def1(&D1),
122 bool isRegPair(
unsigned Reg)
const {
123 return Hexagon::DoubleRegsRegClass.contains(Reg);
126 void getSubRegs(
unsigned Reg,
BitVector &SRs)
const;
127 void expandReg(
unsigned Reg,
BitVector &Set)
const;
132 bool isCondTransfer(
unsigned Opc)
const;
140char HexagonGenMux::ID = 0;
143 "Hexagon generate mux instructions",
false,
false)
145void HexagonGenMux::getSubRegs(
unsigned Reg,
BitVector &SRs)
const {
150void HexagonGenMux::expandReg(
unsigned Reg,
BitVector &Set)
const {
152 getSubRegs(Reg, Set);
160 unsigned Opc =
MI->getOpcode();
169 if (!MO.isReg() || MO.isImplicit())
178 DefUseInfoMap &DUM) {
180 unsigned NR = HRI->getNumRegs();
184 I2X.insert(std::make_pair(&
MI, Index));
187 getDefsUses(&
MI, Defs,
Uses);
188 DUM.insert(std::make_pair(Index, DefUseInfo(Defs,
Uses)));
193bool HexagonGenMux::isCondTransfer(
unsigned Opc)
const {
195 case Hexagon::A2_tfrt:
196 case Hexagon::A2_tfrf:
197 case Hexagon::C2_cmoveit:
198 case Hexagon::C2_cmoveif:
206 bool IsReg1 = Src1.
isReg(), IsReg2 = Src2.
isReg();
208 return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir;
210 return Hexagon::C2_muxri;
215 return Hexagon::C2_muxii;
221 bool Changed =
false;
224 buildMaps(
B, I2X, DUM);
232 unsigned Opc =
MI.getOpcode();
233 if (!isCondTransfer(Opc))
243 unsigned Idx = I2X.lookup(&
MI);
244 CondsetMap::iterator
F = CM.find(DR);
245 bool IfTrue = HII->isPredicatedTrue(Opc);
249 if (
F != CM.end() &&
F->second.PredR != PR) {
254 auto It = CM.insert(std::make_pair(DR, CondsetInfo()));
256 F->second.PredR = PR;
258 CondsetInfo &CI =
F->second;
263 if (CI.TrueX == std::numeric_limits<unsigned>::max() ||
264 CI.FalseX == std::numeric_limits<unsigned>::max())
272 unsigned MinX = std::min(CI.TrueX, CI.FalseX);
273 unsigned MaxX = std::max(CI.TrueX, CI.FalseX);
277 bool NearDef =
false;
278 for (
unsigned X = SearchX;
X < MaxX; ++
X) {
279 const DefUseInfo &DU = DUM.lookup(
X);
295 std::advance(It1, MinX);
296 std::advance(It2, MaxX);
301 bool Failure =
false, CanUp =
true, CanDown =
true;
302 for (
unsigned X = MinX+1;
X < MaxX;
X++) {
303 const DefUseInfo &DU = DUM.lookup(
X);
304 if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) {
308 if (CanDown && DU.Defs[SR1])
310 if (CanUp && DU.Defs[SR2])
313 if (Failure || (!CanUp && !CanDown))
321 ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2));
324 for (MuxInfo &MX :
ML) {
325 unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF);
331 if (!MX.At->getParent() || !MX.Def1->getParent() || !MX.Def2->getParent())
336 auto NewMux =
BuildMI(
B, MX.At,
DL, HII->get(MxOpc), MX.DefR)
351 if (
I.isDebugInstr())
358 if (!
Op.isReg() || !
Op.isUse())
360 assert(
Op.getSubReg() == 0 &&
"Should have physical registers only");
361 bool Live = !LPR.available(
Op.getReg());
375 bool Changed =
false;
377 Changed |= genMuxInBlock(
I);
382 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")
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)
Remove Loads Into Fake Uses
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)