CodeGenInstruction.h [plain text]
#ifndef CODEGEN_INSTRUCTION_H
#define CODEGEN_INSTRUCTION_H
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SourceMgr.h"
#include <string>
#include <vector>
#include <utility>
namespace llvm {
class Record;
class DagInit;
class CodeGenTarget;
class StringRef;
class CGIOperandList {
public:
class ConstraintInfo {
enum { None, EarlyClobber, Tied } Kind;
unsigned OtherTiedOperand;
public:
ConstraintInfo() : Kind(None) {}
static ConstraintInfo getEarlyClobber() {
ConstraintInfo I;
I.Kind = EarlyClobber;
I.OtherTiedOperand = 0;
return I;
}
static ConstraintInfo getTied(unsigned Op) {
ConstraintInfo I;
I.Kind = Tied;
I.OtherTiedOperand = Op;
return I;
}
bool isNone() const { return Kind == None; }
bool isEarlyClobber() const { return Kind == EarlyClobber; }
bool isTied() const { return Kind == Tied; }
unsigned getTiedOperand() const {
assert(isTied());
return OtherTiedOperand;
}
};
struct OperandInfo {
Record *Rec;
std::string Name;
std::string PrinterMethodName;
std::string EncoderMethodName;
std::string OperandType;
unsigned MIOperandNo;
unsigned MINumOperands;
std::vector<bool> DoNotEncode;
DagInit *MIOperandInfo;
std::vector<ConstraintInfo> Constraints;
OperandInfo(Record *R, const std::string &N, const std::string &PMN,
const std::string &EMN, const std::string &OT, unsigned MION,
unsigned MINO, DagInit *MIOI)
: Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
OperandType(OT), MIOperandNo(MION), MINumOperands(MINO),
MIOperandInfo(MIOI) {}
int getTiedRegister() const {
for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
const CGIOperandList::ConstraintInfo &CI = Constraints[j];
if (CI.isTied()) return CI.getTiedOperand();
}
return -1;
}
};
CGIOperandList(Record *D);
Record *TheDef;
unsigned NumDefs;
std::vector<OperandInfo> OperandList;
bool isPredicable;
bool hasOptionalDef;
bool isVariadic;
bool empty() const { return OperandList.empty(); }
unsigned size() const { return OperandList.size(); }
const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
OperandInfo &operator[](unsigned i) { return OperandList[i]; }
OperandInfo &back() { return OperandList.back(); }
const OperandInfo &back() const { return OperandList.back(); }
unsigned getOperandNamed(StringRef Name) const;
bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
bool AllowWholeOp = true);
unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
return OperandList[Op.first].MIOperandNo + Op.second;
}
std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
for (unsigned i = 0; ; ++i) {
assert(i < OperandList.size() && "Invalid flat operand #");
if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
return std::make_pair(i, Op-OperandList[i].MIOperandNo);
}
}
bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
if (OperandList[Op.first].DoNotEncode.size() > Op.second)
return OperandList[Op.first].DoNotEncode[Op.second];
return false;
}
void ProcessDisableEncoding(std::string Value);
};
class CodeGenInstruction {
public:
Record *TheDef; std::string Namespace;
std::string AsmString;
CGIOperandList Operands;
std::vector<Record*> ImplicitDefs, ImplicitUses;
bool isReturn;
bool isBranch;
bool isIndirectBranch;
bool isCompare;
bool isMoveImm;
bool isBitcast;
bool isBarrier;
bool isCall;
bool canFoldAsLoad;
bool mayLoad, mayStore;
bool isPredicable;
bool isConvertibleToThreeAddress;
bool isCommutable;
bool isTerminator;
bool isReMaterializable;
bool hasDelaySlot;
bool usesCustomInserter;
bool hasPostISelHook;
bool hasCtrlDep;
bool isNotDuplicable;
bool hasSideEffects;
bool neverHasSideEffects;
bool isAsCheapAsAMove;
bool hasExtraSrcRegAllocReq;
bool hasExtraDefRegAllocReq;
bool isCodeGenOnly;
bool isPseudo;
CodeGenInstruction(Record *R);
MVT::SimpleValueType
HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
static std::string FlattenAsmStringVariants(StringRef AsmString,
unsigned Variant);
};
class CodeGenInstAlias {
public:
Record *TheDef;
std::string AsmString;
DagInit *Result;
CodeGenInstruction *ResultInst;
struct ResultOperand {
private:
StringRef Name;
Record *R;
int64_t Imm;
public:
enum {
K_Record,
K_Imm,
K_Reg
} Kind;
ResultOperand(StringRef N, Record *r) : Name(N), R(r), Kind(K_Record) {}
ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
bool isRecord() const { return Kind == K_Record; }
bool isImm() const { return Kind == K_Imm; }
bool isReg() const { return Kind == K_Reg; }
StringRef getName() const { assert(isRecord()); return Name; }
Record *getRecord() const { assert(isRecord()); return R; }
int64_t getImm() const { assert(isImm()); return Imm; }
Record *getRegister() const { assert(isReg()); return R; }
};
std::vector<ResultOperand> ResultOperands;
std::vector<std::pair<unsigned, int> > ResultInstOperandIndex;
CodeGenInstAlias(Record *R, CodeGenTarget &T);
bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
Record *InstOpRec, bool hasSubOps, SMLoc Loc,
CodeGenTarget &T, ResultOperand &ResOp);
};
}
#endif