aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/CodeGenTarget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/CodeGenTarget.cpp')
-rw-r--r--utils/TableGen/CodeGenTarget.cpp100
1 files changed, 72 insertions, 28 deletions
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index bcb653135551..b65e1b6af791 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -1,9 +1,8 @@
//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,8 +20,10 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Timer.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
using namespace llvm;
@@ -105,11 +106,18 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v128i16: return "MVT::v128i16";
case MVT::v1i32: return "MVT::v1i32";
case MVT::v2i32: return "MVT::v2i32";
+ case MVT::v3i32: return "MVT::v3i32";
case MVT::v4i32: return "MVT::v4i32";
+ case MVT::v5i32: return "MVT::v5i32";
case MVT::v8i32: return "MVT::v8i32";
case MVT::v16i32: return "MVT::v16i32";
case MVT::v32i32: return "MVT::v32i32";
case MVT::v64i32: return "MVT::v64i32";
+ case MVT::v128i32: return "MVT::v128i32";
+ case MVT::v256i32: return "MVT::v256i32";
+ case MVT::v512i32: return "MVT::v512i32";
+ case MVT::v1024i32: return "MVT::v1024i32";
+ case MVT::v2048i32: return "MVT::v2048i32";
case MVT::v1i64: return "MVT::v1i64";
case MVT::v2i64: return "MVT::v2i64";
case MVT::v4i64: return "MVT::v4i64";
@@ -122,9 +130,18 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v8f16: return "MVT::v8f16";
case MVT::v1f32: return "MVT::v1f32";
case MVT::v2f32: return "MVT::v2f32";
+ case MVT::v3f32: return "MVT::v3f32";
case MVT::v4f32: return "MVT::v4f32";
+ case MVT::v5f32: return "MVT::v5f32";
case MVT::v8f32: return "MVT::v8f32";
case MVT::v16f32: return "MVT::v16f32";
+ case MVT::v32f32: return "MVT::v32f32";
+ case MVT::v64f32: return "MVT::v64f32";
+ case MVT::v128f32: return "MVT::v128f32";
+ case MVT::v256f32: return "MVT::v256f32";
+ case MVT::v512f32: return "MVT::v512f32";
+ case MVT::v1024f32: return "MVT::v1024f32";
+ case MVT::v2048f32: return "MVT::v2048f32";
case MVT::v1f64: return "MVT::v1f64";
case MVT::v2f64: return "MVT::v2f64";
case MVT::v4f64: return "MVT::v4f64";
@@ -174,7 +191,7 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::iPTR: return "MVT::iPTR";
case MVT::iPTRAny: return "MVT::iPTRAny";
case MVT::Untyped: return "MVT::Untyped";
- case MVT::ExceptRef: return "MVT::ExceptRef";
+ case MVT::exnref: return "MVT::exnref";
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
}
}
@@ -327,6 +344,8 @@ CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
}
void CodeGenTarget::ReadInstructions() const {
+ NamedRegionTimer T("Read Instructions", "Time spent reading instructions",
+ "CodeGenTarget", "CodeGenTarget", TimeRegions);
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
if (Insts.size() <= 2)
PrintFatalError("No 'Instruction' subclasses defined!");
@@ -492,9 +511,10 @@ ComplexPattern::ComplexPattern(Record *R) {
} else if (PropList[i]->getName() == "SDNPWantParent") {
Properties |= 1 << SDNPWantParent;
} else {
- PrintFatalError("Unsupported SD Node property '" +
- PropList[i]->getName() + "' on ComplexPattern '" +
- R->getName() + "'!");
+ PrintFatalError(R->getLoc(), "Unsupported SD Node property '" +
+ PropList[i]->getName() +
+ "' on ComplexPattern '" + R->getName() +
+ "'!");
}
}
@@ -530,12 +550,14 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC,
CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
TheDef = R;
std::string DefName = R->getName();
+ ArrayRef<SMLoc> DefLoc = R->getLoc();
ModRef = ReadWriteMem;
Properties = 0;
isOverloaded = false;
isCommutative = false;
canThrow = false;
isNoReturn = false;
+ isWillReturn = false;
isCold = false;
isNoDuplicate = false;
isConvergent = false;
@@ -544,7 +566,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
if (DefName.size() <= 4 ||
std::string(DefName.begin(), DefName.begin() + 4) != "int_")
- PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");
+ PrintFatalError(DefLoc,
+ "Intrinsic '" + DefName + "' does not start with 'int_'!");
EnumName = std::string(DefName.begin()+4, DefName.end());
@@ -566,7 +589,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
// Verify it starts with "llvm.".
if (Name.size() <= 5 ||
std::string(Name.begin(), Name.begin() + 5) != "llvm.")
- PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
+ PrintFatalError(DefLoc, "Intrinsic '" + DefName +
+ "'s name does not start with 'llvm.'!");
}
// If TargetPrefix is specified, make sure that Name starts with
@@ -575,13 +599,34 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
if (Name.size() < 6+TargetPrefix.size() ||
std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
!= (TargetPrefix + "."))
- PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
- TargetPrefix + ".'!");
+ PrintFatalError(DefLoc, "Intrinsic '" + DefName +
+ "' does not start with 'llvm." +
+ TargetPrefix + ".'!");
}
- // Parse the list of return types.
+ ListInit *RetTypes = R->getValueAsListInit("RetTypes");
+ ListInit *ParamTypes = R->getValueAsListInit("ParamTypes");
+
+ // First collate a list of overloaded types.
std::vector<MVT::SimpleValueType> OverloadedVTs;
- ListInit *TypeList = R->getValueAsListInit("RetTypes");
+ for (ListInit *TypeList : {RetTypes, ParamTypes}) {
+ for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
+ Record *TyEl = TypeList->getElementAsRecord(i);
+ assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
+
+ if (TyEl->isSubClassOf("LLVMMatchType"))
+ continue;
+
+ MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
+ if (MVT(VT).isOverloaded()) {
+ OverloadedVTs.push_back(VT);
+ isOverloaded = true;
+ }
+ }
+ }
+
+ // Parse the list of return types.
+ ListInit *TypeList = RetTypes;
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
@@ -601,21 +646,18 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
} else {
VT = getValueType(TyEl->getValueAsDef("VT"));
}
- if (MVT(VT).isOverloaded()) {
- OverloadedVTs.push_back(VT);
- isOverloaded = true;
- }
// Reject invalid types.
if (VT == MVT::isVoid)
- PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
+ PrintFatalError(DefLoc, "Intrinsic '" + DefName +
+ " has void in result type list!");
IS.RetVTs.push_back(VT);
IS.RetTypeDefs.push_back(TyEl);
}
// Parse the list of parameter types.
- TypeList = R->getValueAsListInit("ParamTypes");
+ TypeList = ParamTypes;
for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
@@ -626,7 +668,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
PrintError(R->getLoc(),
"Parameter #" + Twine(i) + " has out of bounds matching "
"number " + Twine(MatchTy));
- PrintFatalError(Twine("ParamTypes is ") + TypeList->getAsString());
+ PrintFatalError(DefLoc,
+ Twine("ParamTypes is ") + TypeList->getAsString());
}
VT = OverloadedVTs[MatchTy];
// It only makes sense to use the extended and truncated vector element
@@ -634,20 +677,16 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
// overloaded, all the types can be specified directly.
assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
!TyEl->isSubClassOf("LLVMTruncatedType") &&
- !TyEl->isSubClassOf("LLVMVectorSameWidth")) ||
+ !TyEl->isSubClassOf("LLVMScalarOrSameVectorWidth")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else
VT = getValueType(TyEl->getValueAsDef("VT"));
- if (MVT(VT).isOverloaded()) {
- OverloadedVTs.push_back(VT);
- isOverloaded = true;
- }
-
// Reject invalid types.
if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
- PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
+ PrintFatalError(DefLoc, "Intrinsic '" + DefName +
+ " has void in result type list!");
IS.ParamVTs.push_back(VT);
IS.ParamTypeDefs.push_back(TyEl);
@@ -683,6 +722,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
isConvergent = true;
else if (Property->getName() == "IntrNoReturn")
isNoReturn = true;
+ else if (Property->getName() == "IntrWillReturn")
+ isWillReturn = true;
else if (Property->getName() == "IntrCold")
isCold = true;
else if (Property->getName() == "IntrSpeculatable")
@@ -704,6 +745,9 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
} else if (Property->isSubClassOf("ReadNone")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
+ } else if (Property->isSubClassOf("ImmArg")) {
+ unsigned ArgNo = Property->getValueAsInt("ArgNo");
+ ArgumentAttributes.push_back(std::make_pair(ArgNo, ImmArg));
} else
llvm_unreachable("Unknown property!");
}