/// getTarget - Return the current instance of the Target class.
///
CodeGenTarget::CodeGenTarget(RecordKeeper &records)
- : Records(records), RegBank(0), SchedModels(0) {
+ : Records(records) {
std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
if (Targets.size() == 0)
PrintFatalError("ERROR: No 'Target' subclasses defined!");
CodeGenTarget::~CodeGenTarget() {
DeleteContainerSeconds(Instructions);
- delete RegBank;
- delete SchedModels;
}
const std::string &CodeGenTarget::getName() const {
Record *CodeGenTarget::getAsmParser() const {
std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
if (AsmParserNum >= LI.size())
- PrintFatalError("Target does not have an AsmParser #" + utostr(AsmParserNum) + "!");
+ PrintFatalError("Target does not have an AsmParser #" +
+ Twine(AsmParserNum) + "!");
return LI[AsmParserNum];
}
std::vector<Record*> LI =
TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
if (i >= LI.size())
- PrintFatalError("Target does not have an AsmParserVariant #" + utostr(i) + "!");
+ PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) +
+ "!");
return LI[i];
}
Record *CodeGenTarget::getAsmWriter() const {
std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
if (AsmWriterNum >= LI.size())
- PrintFatalError("Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!");
+ PrintFatalError("Target does not have an AsmWriter #" +
+ Twine(AsmWriterNum) + "!");
return LI[AsmWriterNum];
}
CodeGenRegBank &CodeGenTarget::getRegBank() const {
if (!RegBank)
- RegBank = new CodeGenRegBank(Records);
+ RegBank = llvm::make_unique<CodeGenRegBank>(Records);
return *RegBank;
}
const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName();
StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name);
if (I == Regs.end())
- return 0;
+ return nullptr;
return I->second;
}
getRegisterVTs(Record *R) const {
const CodeGenRegister *Reg = getRegBank().getReg(R);
std::vector<MVT::SimpleValueType> Result;
- ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
- for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
- const CodeGenRegisterClass &RC = *RCs[i];
+ for (const auto &RC : getRegBank().getRegClasses()) {
if (RC.contains(Reg)) {
ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
Result.insert(Result.end(), InVTs.begin(), InVTs.end());
void CodeGenTarget::ReadLegalValueTypes() const {
- ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
- for (unsigned i = 0, e = RCs.size(); i != e; ++i)
- for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri)
- LegalValueTypes.push_back(RCs[i]->VTs[ri]);
+ for (const auto &RC : getRegBank().getRegClasses())
+ LegalValueTypes.insert(LegalValueTypes.end(), RC.VTs.begin(), RC.VTs.end());
// Remove duplicates.
std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
if (!SchedModels)
- SchedModels = new CodeGenSchedModels(Records, *this);
+ SchedModels = llvm::make_unique<CodeGenSchedModels>(Records, *this);
return *SchedModels;
}
DenseMap<const Record*, CodeGenInstruction*>::const_iterator
I = Insts.find(Rec);
- if (Rec == 0 || I == Insts.end())
- PrintFatalError(std::string("Could not find '") + Name + "' instruction!");
+ if (!Rec || I == Insts.end())
+ PrintFatalError(Twine("Could not find '") + Name + "' instruction!");
return I->second;
}
-namespace {
-/// SortInstByName - Sorting predicate to sort instructions by name.
-///
-struct SortInstByName {
- bool operator()(const CodeGenInstruction *Rec1,
- const CodeGenInstruction *Rec2) const {
- return Rec1->TheDef->getName() < Rec2->TheDef->getName();
- }
-};
-}
-
/// \brief Return all of the instructions defined by the target, ordered by
/// their enum value.
void CodeGenTarget::ComputeInstrsByEnum() const {
// The ordering here must match the ordering in TargetOpcodes.h.
static const char *const FixedInstrs[] = {
- "PHI",
- "INLINEASM",
- "PROLOG_LABEL",
- "EH_LABEL",
- "GC_LABEL",
- "KILL",
- "EXTRACT_SUBREG",
- "INSERT_SUBREG",
- "IMPLICIT_DEF",
- "SUBREG_TO_REG",
- "COPY_TO_REGCLASS",
- "DBG_VALUE",
- "REG_SEQUENCE",
- "COPY",
- "BUNDLE",
- "LIFETIME_START",
- "LIFETIME_END",
- "STACKMAP",
- "PATCHPOINT",
- 0
- };
+ "PHI", "INLINEASM", "CFI_INSTRUCTION", "EH_LABEL",
+ "GC_LABEL", "KILL", "EXTRACT_SUBREG", "INSERT_SUBREG",
+ "IMPLICIT_DEF", "SUBREG_TO_REG", "COPY_TO_REGCLASS", "DBG_VALUE",
+ "REG_SEQUENCE", "COPY", "BUNDLE", "LIFETIME_START",
+ "LIFETIME_END", "STACKMAP", "PATCHPOINT", "LOAD_STACK_GUARD",
+ "STATEPOINT",
+ nullptr};
const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
for (const char *const *p = FixedInstrs; *p; ++p) {
const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
// All of the instructions are now in random order based on the map iteration.
// Sort them by name.
- std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(),
- SortInstByName());
+ std::sort(InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
+ [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
+ return Rec1->TheDef->getName() < Rec2->TheDef->getName();
+ });
}
isCommutative = false;
canThrow = false;
isNoReturn = false;
+ isNoDuplicate = false;
if (DefName.size() <= 4 ||
std::string(DefName.begin(), DefName.begin() + 4) != "int_")
if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
+ if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field.
+ MSBuiltinName = R->getValueAsString("MSBuiltinName");
TargetPrefix = R->getValueAsString("TargetPrefix");
Name = R->getValueAsString("LLVMName");
// It only makes sense to use the extended and truncated vector element
// variants with iAny types; otherwise, if the intrinsic is not
// overloaded, all the types can be specified directly.
- assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
- !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+ assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
+ !TyEl->isSubClassOf("LLVMTruncatedType")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else {
// It only makes sense to use the extended and truncated vector element
// variants with iAny types; otherwise, if the intrinsic is not
// overloaded, all the types can be specified directly.
- assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
- !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+ assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
+ !TyEl->isSubClassOf("LLVMTruncatedType")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else
isCommutative = true;
else if (Property->getName() == "Throws")
canThrow = true;
+ else if (Property->getName() == "IntrNoDuplicate")
+ isNoDuplicate = true;
else if (Property->getName() == "IntrNoReturn")
isNoReturn = true;
else if (Property->isSubClassOf("NoCapture")) {