diff options
Diffstat (limited to 'llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp')
| -rw-r--r-- | llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp index ff894853b977..d90fcc25502e 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -13,6 +13,7 @@ #include "CodeGenIntrinsics.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/TableGen/Error.h" @@ -377,7 +378,19 @@ void CodeGenIntrinsic::setProperty(const Record *R) { ME &= MemoryEffects::argMemOnly(); else if (R->getName() == "IntrInaccessibleMemOnly") ME &= MemoryEffects::inaccessibleMemOnly(); - else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") + else if (R->isSubClassOf("IntrRead")) { + MemoryEffects ReadMask = MemoryEffects::writeOnly(); + for (const Record *RLoc : R->getValueAsListOfDefs("MemLoc")) + ReadMask = ReadMask.getWithModRef(getValueAsIRMemLocation(RLoc), + ModRefInfo::ModRef); + ME &= ReadMask; + } else if (R->isSubClassOf("IntrWrite")) { + MemoryEffects WriteMask = MemoryEffects::readOnly(); + for (const Record *WLoc : R->getValueAsListOfDefs("MemLoc")) + WriteMask = WriteMask.getWithModRef(getValueAsIRMemLocation(WLoc), + ModRefInfo::ModRef); + ME &= WriteMask; + } else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") ME &= MemoryEffects::inaccessibleOrArgMemOnly(); else if (R->getName() == "Commutative") isCommutative = true; @@ -449,11 +462,50 @@ void CodeGenIntrinsic::setProperty(const Record *R) { int64_t Lower = R->getValueAsInt("Lower"); int64_t Upper = R->getValueAsInt("Upper"); addArgAttribute(ArgNo, Range, Lower, Upper); + } else if (R->isSubClassOf("ArgInfo")) { + unsigned ArgNo = R->getValueAsInt("ArgNo"); + if (ArgNo < 1) + PrintFatalError(R->getLoc(), + "ArgInfo requires ArgNo >= 1 (0 is return value)"); + const ListInit *Properties = R->getValueAsListInit("Properties"); + StringRef ArgName; + StringRef FuncName; + + for (const Init *PropInit : Properties->getElements()) { + if (const auto *PropDef = dyn_cast<DefInit>(PropInit)) { + const Record *PropRec = PropDef->getDef(); + + if (PropRec->isSubClassOf("ArgName")) + ArgName = PropRec->getValueAsString("Name"); + else if (PropRec->isSubClassOf("ImmArgPrinter")) + FuncName = PropRec->getValueAsString("FuncName"); + else + PrintFatalError(PropRec->getLoc(), + "Unknown ArgProperty type: " + PropRec->getName()); + } + } + addPrettyPrintFunction(ArgNo - 1, ArgName, FuncName); } else { llvm_unreachable("Unknown property!"); } } +llvm::IRMemLocation +CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R) const { + StringRef Name = R->getName(); + IRMemLocation Loc = + StringSwitch<IRMemLocation>(Name) + .Case("TargetMem0", IRMemLocation::TargetMem0) + .Case("TargetMem1", IRMemLocation::TargetMem1) + .Case("InaccessibleMem", IRMemLocation::InaccessibleMem) + .Default(IRMemLocation::Other); // fallback enum + + if (Loc == IRMemLocation::Other) + PrintFatalError(R->getLoc(), "unknown IRMemLocation: " + Name); + + return Loc; +} + bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const { if (ParamIdx >= IS.ParamTys.size()) return false; @@ -476,3 +528,16 @@ void CodeGenIntrinsic::addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V, ArgumentAttributes.resize(Idx + 1); ArgumentAttributes[Idx].emplace_back(AK, V, V2); } + +void CodeGenIntrinsic::addPrettyPrintFunction(unsigned ArgIdx, + StringRef ArgName, + StringRef FuncName) { + auto It = llvm::find_if(PrettyPrintFunctions, [ArgIdx](const auto &Info) { + return Info.ArgIdx == ArgIdx; + }); + if (It != PrettyPrintFunctions.end()) + PrintFatalError(TheDef->getLoc(), "ArgInfo for argument " + Twine(ArgIdx) + + " is already defined as '" + + It->FuncName + "'"); + PrettyPrintFunctions.emplace_back(ArgIdx, ArgName, FuncName); +} |
