Go to the documentation of this file.
36 const HexagonMCChecker::PredSense
37 HexagonMCChecker::Unconditional(Hexagon::NoRegister,
false);
39 void HexagonMCChecker::init() {
41 ReadOnly.insert(Hexagon::PC);
42 ReadOnly.insert(Hexagon::C9_8);
46 Defs[Hexagon::SA0].
insert(Unconditional);
50 Defs[Hexagon::SA1].
insert(Unconditional);
51 Defs[Hexagon::LC1].
insert(Unconditional);
57 MCInst const &Inst = *
I.getInst();
68 void HexagonMCChecker::initReg(
MCInst const &MCI,
unsigned R,
unsigned &PredReg,
78 NewPreds.insert(PredReg);
89 ReversePairs.insert(R);
92 void HexagonMCChecker::init(
MCInst const &MCI) {
94 unsigned PredReg = Hexagon::NoRegister;
110 for (; *ImpDef; ++ImpDef) {
111 unsigned R = *ImpDef;
113 if (Hexagon::R31 != R && MCID.
isCall())
117 if (Hexagon::PC == R)
122 if (Hexagon::USR_OVF == R)
133 else if (!IgnoreTmpDst)
134 Defs[
R].
insert(PredSense(PredReg, isTrue));
143 if (R == Hexagon::C8)
147 ReversePairs.insert(R);
166 if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI)
171 SoftDefs.insert(*SRI);
175 LatePreds.insert(*SRI);
183 TmpDefs.insert(*SRI);
188 else if (!IgnoreTmpDst)
189 Defs[*SRI].
insert(PredSense(PredReg, isTrue));
208 ReportErrors(ReportErrors) {
214 bool CopyReportErrors)
216 STI(STI), ReportErrors(CopyReportErrors ?
Other.ReportErrors :
false) {
221 bool chkP = checkPredicates();
222 bool chkNV = checkNewValues();
223 bool chkR = checkRegisters();
224 bool chkRRO = checkRegistersReadOnly();
225 checkRegisterCurDefs();
226 bool chkS = checkSolo();
229 chkSh = checkShuffle();
232 chkSl = checkSlots();
233 bool chkAXOK = checkAXOK();
234 bool chkCofMax1 = checkCOFMax1();
235 bool chkHWLoop = checkHWLoop();
236 bool chkValidTmpDst = FullCheck ? checkValidTmpDst() :
true;
237 bool chkLegalVecRegPair = checkLegalVecRegPair();
238 bool ChkHVXAccum = checkHVXAccum();
239 bool chk = chkP && chkNV && chkR && chkRRO && chkS && chkSh && chkSl &&
240 chkAXOK && chkCofMax1 && chkHWLoop && chkValidTmpDst &&
241 chkLegalVecRegPair && ChkHVXAccum;
248 case Hexagon::SA1_addi:
249 case Hexagon::SA1_addrx:
250 case Hexagon::SA1_addsp:
251 case Hexagon::SA1_and1:
252 case Hexagon::SA1_clrf:
253 case Hexagon::SA1_clrfnew:
254 case Hexagon::SA1_clrt:
255 case Hexagon::SA1_clrtnew:
256 case Hexagon::SA1_cmpeqi:
257 case Hexagon::SA1_combine0i:
258 case Hexagon::SA1_combine1i:
259 case Hexagon::SA1_combine2i:
260 case Hexagon::SA1_combine3i:
261 case Hexagon::SA1_combinerz:
262 case Hexagon::SA1_combinezr:
263 case Hexagon::SA1_dec:
264 case Hexagon::SA1_inc:
265 case Hexagon::SA1_seti:
266 case Hexagon::SA1_setin1:
267 case Hexagon::SA1_sxtb:
268 case Hexagon::SA1_sxth:
269 case Hexagon::SA1_tfr:
270 case Hexagon::SA1_zxtb:
271 case Hexagon::SA1_zxth:
303 bool HexagonMCChecker::checkAXOK() {
304 MCInst const *HasSoloAXInst =
nullptr;
316 Twine(
"Instruction can only be in a packet with ALU or non-FPU XTYPE "
319 Twine(
"Not an ALU or non-FPU XTYPE instruction"));
333 bool HexagonMCChecker::checkHWLoop() {
340 "Branches cannot be in a packet with hardware loops");
348 bool HexagonMCChecker::checkCOFMax1() {
352 BranchLocations.push_back(&
I);
354 for (
unsigned J = 0,
N = BranchLocations.size(); J <
N; ++J) {
355 MCInst const &
I = *BranchLocations[J];
359 if (
N > 1 && !Relax1 && !Relax2) {
361 "Instruction may not be in a packet with other branches");
365 if (
N > 1 && J == 0 && !Relax1) {
367 "Instruction may not be the first branch in packet");
371 if (
N > 1 && J == 1 && !Relax2) {
373 "Instruction may not be the second branch in packet");
382 bool HexagonMCChecker::checkSlots() {
385 reportError(
"invalid instruction packet: out of slots");
392 bool HexagonMCChecker::checkPredicates() {
394 for (
const auto &
I : NewPreds) {
397 if (!Defs.
count(
P) || LatePreds.count(
P) || Defs.
count(Hexagon::P3_0)) {
407 for (
const auto &
I : LatePreds) {
410 if (LatePreds.count(
P) > 1 || Defs.
count(
P)) {
423 bool HexagonMCChecker::checkNewValues() {
424 for (
auto const &ConsumerInst :
437 auto Producer = registerProducer(
Op.getReg(), ConsumerPredInfo);
438 const MCInst *
const ProducerInst = std::get<0>(Producer);
440 std::get<2>(Producer);
442 if (ProducerInst ==
nullptr) {
444 "New value register consumer has no producer");
455 "Register producer is predicated and consumer is unconditional");
457 "Instruction does not have a valid new register producer");
460 if (ProducerPredInfo.
Register != Hexagon::NoRegister &&
463 "Register producer does not use the same predicate "
464 "register as the consumer");
466 "Instruction does not have a valid new register producer");
474 "Register producer has the opposite predicate sense as consumer");
476 "Instruction does not have a valid new register producer");
481 const unsigned ProducerOpIndex = std::get<1>(Producer);
484 Hexagon::DoubleRegsRegClassID) {
486 "Double registers cannot be new-value producers");
488 "Instruction does not have a valid new register producer");
496 const unsigned ProducerOpSearchIndex =
502 const bool ProducerOpIsMemIndex =
503 ((Desc.
mayLoad() && ProducerOpIndex == ProducerOpSearchIndex) ||
504 (Desc.
mayStore() && ProducerOpIndex == 0));
506 if (ProducerOpIsMemIndex) {
511 ModeError =
"Absolute-set";
513 ModeError =
"Auto-increment";
514 if (!ModeError.
empty()) {
516 ModeError +
" registers cannot be a new-value "
519 "Instruction does not have a valid new register producer");
525 "FPU instructions cannot be new-value producers for jumps");
527 "Instruction does not have a valid new register producer");
534 bool HexagonMCChecker::checkRegistersReadOnly() {
536 MCInst const &Inst = *
I.getInst();
538 for (
unsigned j = 0;
j < Defs; ++
j) {
540 assert(Operand.
isReg() &&
"Def is not a register");
542 if (ReadOnly.find(
Register) != ReadOnly.end()) {
552 bool HexagonMCChecker::registerUsed(
unsigned Register) {
555 n =
I.getNumOperands();
564 std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
565 HexagonMCChecker::registerProducer(
567 std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
579 (ProducerPredicate.Register == ConsumerPredicate.
Register &&
580 (ProducerPredicate.Register == Hexagon::NoRegister ||
581 ProducerPredicate.PredicatedTrue ==
583 return std::make_tuple(&
I, J, ProducerPredicate);
584 std::get<0>(WrongSense) = &
I;
585 std::get<1>(WrongSense) = J;
586 std::get<2>(WrongSense) = ProducerPredicate;
594 void HexagonMCChecker::checkRegisterCurDefs() {
598 const unsigned RegDef =
I.getOperand(0).getReg();
600 bool HasRegDefUse =
false;
603 HasRegDefUse = HasRegDefUse || registerUsed(*Alias);
607 "' used with `.cur' "
608 "but not used in the same packet");
614 bool HexagonMCChecker::checkRegisters() {
616 for (
const auto &
I : Defs) {
617 unsigned R =
I.first;
619 if (isLoopRegister(R) && Defs.count(R) > 1 &&
623 reportError(
"loop-setup and some branch instructions "
624 "cannot be in the same packet");
627 if (SoftDefs.count(R)) {
630 unsigned UsrR = Hexagon::USR;
637 PredSet &PM = Defs[
R];
640 if (PM.count(Unconditional)) {
643 unsigned UsrR = Hexagon::USR;
649 for (
const auto &J : PM) {
653 if (PM.count(
P) > 1) {
660 P.second = !
P.second;
661 if (PM.count(
P) && PM.size() > 2) {
673 for (
const auto &
I : TmpDefs) {
676 if (!Uses.count(R)) {
678 bool vHistFound =
false;
689 "' used with `.tmp' but not used in the same packet");
699 bool HexagonMCChecker::checkSolo() {
703 reportError(
I.getLoc(),
"Instruction is marked `isSolo' and "
704 "cannot have other instructions in "
713 bool HexagonMCChecker::checkShuffle() {
715 return MCSDX.check();
718 bool HexagonMCChecker::checkValidTmpDst() {
722 auto HasTmp = [&](
MCInst const &
I) {
726 unsigned HasTmpCount =
729 if (HasTmpCount > 1) {
732 "this packet has more than one HVX vtmp/.tmp destination instruction");
737 "this is an HVX vtmp/.tmp destination instruction");
744 void HexagonMCChecker::compoundRegisterMap(
unsigned &
Register) {
777 "' modified more than once");
782 "' used with `.new' "
783 "but not validly modified in the same packet");
808 bool HexagonMCChecker::checkLegalVecRegPair() {
810 const bool HasReversePairs = ReversePairs.size() != 0;
812 if (!IsPermitted && HasReversePairs) {
813 for (
auto R : ReversePairs)
815 "' is not permitted for this architecture");
822 bool HexagonMCChecker::checkHVXAccum()
829 unsigned int R =
I.getOperand(0).getReg();
830 TmpDefsIterator It = TmpDefs.find(R);
831 if (It != TmpDefs.end()) {
833 "' is accumulated in this packet");
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
This is an optimization pass for GlobalISel generic memory operations.
const MCInstrDesc & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
bool isAccumulator(MCInstrInfo const &MCII, MCInst const &MCI)
Return where the instruction is an accumulator.
bool isPredReg(MCRegisterInfo const &MRI, unsigned Reg)
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool IsABranchingInst(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &I)
Context object for machine code objects.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
bool isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool isCofRelax2(MCInstrInfo const &MCII, MCInst const &MCI)
void reportError(SMLoc Loc, Twine const &Msg)
bool hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPredicated() const
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Instances of this class represent a single low-level machine instruction.
void reportNote(SMLoc Loc, Twine const &Msg)
bool isCofRelax1(MCInstrInfo const &MCII, MCInst const &MCI)
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
void reportWarning(Twine const &Msg)
bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI)
Represents a location in source code.
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a second value.
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn expects newly produced value.
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
const MCInst * getInst() const
unsigned getNumImplicitUses() const
Return the number of implicit uses this instruction has.
static bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID)
bool isBundle(MCInst const &MCI)
const MCPhysReg * getImplicitDefs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
PredicateInfo predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI)
bool check(bool FullCheck=true)
Describe properties that are true of each instruction in the target description file.
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
const FeatureBitset & getFeatureBits() const
bool hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI)
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
size_t bundleSize(MCInst const &MCI)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
void reportErrorNewValue(unsigned Register)
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with A and X-type insns.
bool isCVINew(MCInstrInfo const &MCII, MCInst const &MCI)
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
bool isCall() const
Return true if the instruction is a call.
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
void reportBranchErrors()
initializer< Ty > init(const Ty &Val)
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, const MCRegisterInfo &ri, bool ReportErrors=true)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsReverseVecRegPair(unsigned VecReg)
void reportError(SMLoc L, const Twine &Msg)
const MCOperandInfo * OpInfo
bool isFloat(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether it is a floating-point insn.
void reportErrorRegisters(unsigned Register)
bool mayStore() const
Return true if this instruction could possibly modify memory.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool isOuterLoop(MCInst const &MCI)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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
const MCOperand & getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
Wrapper class representing virtual and physical registers.
const CustomOperand< const MCSubtargetInfo & > Msg[]
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Interface to description of machine instruction set.
Check for a valid bundle.
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
into eax xorps xmm0 xmm0 eax xmm0 eax xmm0 ret esp eax movdqa LC0
bool isSubRegister(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA.
unsigned packetSizeSlots(MCSubtargetInfo const &STI)
MCSubRegIterator enumerates all sub-registers of Reg.
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
const SourceMgr * getSourceManager() const
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
const MCOperand & getOperand(unsigned i) const
Instances of this class represent operands of the MCInst class.
bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is solo, i.e., cannot be in a packet.
static bool isDuplexAGroup(unsigned Opcode)
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
unsigned slotsConsumed(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI)
Generic base class for all target subtargets.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
static cl::opt< bool > RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value validity"))
const MCPhysReg * getImplicitUses() const
Return a list of registers that are potentially read by any instance of this machine instruction.
MCRegAliasIterator enumerates all registers aliasing Reg.
Optional< std::vector< StOtherPiece > > Other
bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is newly predicated.
void reportWarning(SMLoc L, const Twine &Msg)
unsigned getReg() const
Returns the register number.
bool isInnerLoop(MCInst const &MCI)