aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp78
-rw-r--r--llvm/lib/IR/Attributes.cpp5
-rw-r--r--llvm/lib/IR/BasicBlock.cpp18
-rw-r--r--llvm/lib/IR/Constants.cpp94
-rw-r--r--llvm/lib/IR/DebugProgramInstruction.cpp40
-rw-r--r--llvm/lib/IR/Instructions.cpp1
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp2
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h4
8 files changed, 218 insertions, 24 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 251485a..fba404c 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -292,8 +292,8 @@ static const Module *getModuleFromDPI(const DPMarker *Marker) {
return M ? M->getParent() : nullptr;
}
-static const Module *getModuleFromDPI(const DPValue *DPV) {
- return DPV->getMarker() ? getModuleFromDPI(DPV->getMarker()) : nullptr;
+static const Module *getModuleFromDPI(const DbgRecord *DR) {
+ return DR->getMarker() ? getModuleFromDPI(DR->getMarker()) : nullptr;
}
static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
@@ -1141,12 +1141,14 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) {
CreateMetadataSlot(DPV->getVariable());
- CreateMetadataSlot(DPV->getDebugLoc());
if (DPV->isDbgAssign())
CreateMetadataSlot(DPV->getAssignID());
+ } else if (const DPLabel *DPL = dyn_cast<const DPLabel>(&DR)) {
+ CreateMetadataSlot(DPL->getLabel());
} else {
llvm_unreachable("unsupported DbgRecord kind");
}
+ CreateMetadataSlot(DR.getDebugLoc());
}
void SlotTracker::processInstructionMetadata(const Instruction &I) {
@@ -1505,16 +1507,39 @@ static void WriteAPFloatInternal(raw_ostream &Out, const APFloat &APF) {
static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
AsmWriterContext &WriterCtx) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- if (CI->getType()->isIntegerTy(1)) {
- Out << (CI->getZExtValue() ? "true" : "false");
- return;
+ Type *Ty = CI->getType();
+
+ if (Ty->isVectorTy()) {
+ Out << "splat (";
+ WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
+ Out << " ";
}
- Out << CI->getValue();
+
+ if (Ty->getScalarType()->isIntegerTy(1))
+ Out << (CI->getZExtValue() ? "true" : "false");
+ else
+ Out << CI->getValue();
+
+ if (Ty->isVectorTy())
+ Out << ")";
+
return;
}
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+ Type *Ty = CFP->getType();
+
+ if (Ty->isVectorTy()) {
+ Out << "splat (";
+ WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
+ Out << " ";
+ }
+
WriteAPFloatInternal(Out, CFP->getValueAPF());
+
+ if (Ty->isVectorTy())
+ Out << ")";
+
return;
}
@@ -2676,6 +2701,7 @@ public:
void printInstruction(const Instruction &I);
void printDPMarker(const DPMarker &DPI);
void printDPValue(const DPValue &DPI);
+ void printDPLabel(const DPLabel &DPL);
void printDbgRecord(const DbgRecord &DPI);
void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
@@ -4579,8 +4605,10 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
void AssemblyWriter::printDbgRecord(const DbgRecord &DR) {
if (auto *DPV = dyn_cast<DPValue>(&DR))
printDPValue(*DPV);
+ else if (auto *DPL = dyn_cast<DPLabel>(&DR))
+ printDPLabel(*DPL);
else
- llvm_unreachable("unsupported dbg record");
+ llvm_unreachable("Unexpected DbgRecord kind");
}
void AssemblyWriter::printDPValue(const DPValue &Value) {
@@ -4622,6 +4650,16 @@ void AssemblyWriter::printDPValue(const DPValue &Value) {
Out << " }";
}
+void AssemblyWriter::printDPLabel(const DPLabel &Label) {
+ // There's no formal representation of a DPLabel -- print purely as
+ // a debugging aid.
+ Out << " DPLabel { ";
+ auto WriterCtx = getContext();
+ WriteAsOperandInternal(Out, Label.getLabel(), WriterCtx, true);
+ Out << " marker @" << Label.getMarker();
+ Out << " }";
+}
+
void AssemblyWriter::printMetadataAttachments(
const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
StringRef Separator) {
@@ -4885,6 +4923,12 @@ void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST,
W.printDPMarker(*this);
}
+void DPLabel::print(raw_ostream &ROS, bool IsForDebug) const {
+
+ ModuleSlotTracker MST(getModuleFromDPI(this), true);
+ print(ROS, MST, IsForDebug);
+}
+
void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
bool IsForDebug) const {
// There's no formal representation of a DPValue -- print purely as a
@@ -4904,6 +4948,24 @@ void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
W.printDPValue(*this);
}
+void DPLabel::print(raw_ostream &ROS, ModuleSlotTracker &MST,
+ bool IsForDebug) const {
+ // There's no formal representation of a DbgLabelRecord -- print purely as
+ // a debugging aid.
+ formatted_raw_ostream OS(ROS);
+ SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
+ SlotTracker &SlotTable =
+ MST.getMachine() ? *MST.getMachine() : EmptySlotTable;
+ auto incorporateFunction = [&](const Function *F) {
+ if (F)
+ MST.incorporateFunction(*F);
+ };
+ incorporateFunction(Marker->getParent() ? Marker->getParent()->getParent()
+ : nullptr);
+ AssemblyWriter W(OS, SlotTable, getModuleFromDPI(this), nullptr, IsForDebug);
+ W.printDPLabel(*this);
+}
+
void Value::print(raw_ostream &ROS, bool IsForDebug) const {
bool ShouldInitializeAllMetadata = false;
if (auto *I = dyn_cast<Instruction>(this))
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index fd51602..1907677 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -2045,6 +2045,11 @@ static bool isEqual(const Function &Caller, const Function &Callee) {
Callee.getFnAttribute(AttrClass::getKind());
}
+static bool isEqual(const Function &Caller, const Function &Callee,
+ const StringRef &AttrName) {
+ return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
+}
+
/// Compute the logical AND of the attributes of the caller and the
/// callee.
///
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index 06807544..6ea876f 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -81,6 +81,12 @@ void BasicBlock::convertToNewDbgValues() {
continue;
}
+ if (DbgLabelInst *DLI = dyn_cast<DbgLabelInst>(&I)) {
+ DPVals.push_back(new DPLabel(DLI->getLabel(), DLI->getDebugLoc()));
+ DLI->eraseFromParent();
+ continue;
+ }
+
if (DPVals.empty())
continue;
@@ -107,16 +113,12 @@ void BasicBlock::convertFromNewDbgValues() {
continue;
DPMarker &Marker = *Inst.DbgMarker;
- for (DbgRecord &DR : Marker.getDbgValueRange()) {
- if (auto *DPV = dyn_cast<DPValue>(&DR))
- InstList.insert(Inst.getIterator(),
- DPV->createDebugIntrinsic(getModule(), nullptr));
- else
- llvm_unreachable("unsupported DbgRecord kind");
- }
+ for (DbgRecord &DR : Marker.getDbgValueRange())
+ InstList.insert(Inst.getIterator(),
+ DR.createDebugIntrinsic(getModule(), nullptr));
Marker.eraseFromParent();
- };
+ }
// Assume no trailing DPValues: we could technically create them at the end
// of the block, after a terminator, but this would be non-cannonical and
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index a38b912..e6b92aa 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -35,6 +35,20 @@
using namespace llvm;
using namespace PatternMatch;
+// As set of temporary options to help migrate how splats are represented.
+static cl::opt<bool> UseConstantIntForFixedLengthSplat(
+ "use-constant-int-for-fixed-length-splat", cl::init(false), cl::Hidden,
+ cl::desc("Use ConstantInt's native fixed-length vector splat support."));
+static cl::opt<bool> UseConstantFPForFixedLengthSplat(
+ "use-constant-fp-for-fixed-length-splat", cl::init(false), cl::Hidden,
+ cl::desc("Use ConstantFP's native fixed-length vector splat support."));
+static cl::opt<bool> UseConstantIntForScalableSplat(
+ "use-constant-int-for-scalable-splat", cl::init(false), cl::Hidden,
+ cl::desc("Use ConstantInt's native scalable vector splat support."));
+static cl::opt<bool> UseConstantFPForScalableSplat(
+ "use-constant-fp-for-scalable-splat", cl::init(false), cl::Hidden,
+ cl::desc("Use ConstantFP's native scalable vector splat support."));
+
//===----------------------------------------------------------------------===//
// Constant Class
//===----------------------------------------------------------------------===//
@@ -825,9 +839,11 @@ bool Constant::isManifestConstant() const {
// ConstantInt
//===----------------------------------------------------------------------===//
-ConstantInt::ConstantInt(IntegerType *Ty, const APInt &V)
+ConstantInt::ConstantInt(Type *Ty, const APInt &V)
: ConstantData(Ty, ConstantIntVal), Val(V) {
- assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
+ assert(V.getBitWidth() ==
+ cast<IntegerType>(Ty->getScalarType())->getBitWidth() &&
+ "Invalid constant for type");
}
ConstantInt *ConstantInt::getTrue(LLVMContext &Context) {
@@ -885,6 +901,26 @@ ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) {
return Slot.get();
}
+// Get a ConstantInt vector with each lane set to the same APInt.
+ConstantInt *ConstantInt::get(LLVMContext &Context, ElementCount EC,
+ const APInt &V) {
+ // Get an existing value or the insertion position.
+ std::unique_ptr<ConstantInt> &Slot =
+ Context.pImpl->IntSplatConstants[std::make_pair(EC, V)];
+ if (!Slot) {
+ IntegerType *ITy = IntegerType::get(Context, V.getBitWidth());
+ VectorType *VTy = VectorType::get(ITy, EC);
+ Slot.reset(new ConstantInt(VTy, V));
+ }
+
+#ifndef NDEBUG
+ IntegerType *ITy = IntegerType::get(Context, V.getBitWidth());
+ VectorType *VTy = VectorType::get(ITy, EC);
+ assert(Slot->getType() == VTy);
+#endif
+ return Slot.get();
+}
+
Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {
Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned);
@@ -1024,6 +1060,26 @@ ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
return Slot.get();
}
+// Get a ConstantFP vector with each lane set to the same APFloat.
+ConstantFP *ConstantFP::get(LLVMContext &Context, ElementCount EC,
+ const APFloat &V) {
+ // Get an existing value or the insertion position.
+ std::unique_ptr<ConstantFP> &Slot =
+ Context.pImpl->FPSplatConstants[std::make_pair(EC, V)];
+ if (!Slot) {
+ Type *EltTy = Type::getFloatingPointTy(Context, V.getSemantics());
+ VectorType *VTy = VectorType::get(EltTy, EC);
+ Slot.reset(new ConstantFP(VTy, V));
+ }
+
+#ifndef NDEBUG
+ Type *EltTy = Type::getFloatingPointTy(Context, V.getSemantics());
+ VectorType *VTy = VectorType::get(EltTy, EC);
+ assert(Slot->getType() == VTy);
+#endif
+ return Slot.get();
+}
+
Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
const fltSemantics &Semantics = Ty->getScalarType()->getFltSemantics();
Constant *C = get(Ty->getContext(), APFloat::getInf(Semantics, Negative));
@@ -1036,7 +1092,7 @@ Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
: ConstantData(Ty, ConstantFPVal), Val(V) {
- assert(&V.getSemantics() == &Ty->getFltSemantics() &&
+ assert(&V.getSemantics() == &Ty->getScalarType()->getFltSemantics() &&
"FP type Mismatch");
}
@@ -1356,11 +1412,13 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
bool isZero = C->isNullValue();
bool isUndef = isa<UndefValue>(C);
bool isPoison = isa<PoisonValue>(C);
+ bool isSplatFP = UseConstantFPForFixedLengthSplat && isa<ConstantFP>(C);
+ bool isSplatInt = UseConstantIntForFixedLengthSplat && isa<ConstantInt>(C);
- if (isZero || isUndef) {
+ if (isZero || isUndef || isSplatFP || isSplatInt) {
for (unsigned i = 1, e = V.size(); i != e; ++i)
if (V[i] != C) {
- isZero = isUndef = isPoison = false;
+ isZero = isUndef = isPoison = isSplatFP = isSplatInt = false;
break;
}
}
@@ -1371,6 +1429,12 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
return PoisonValue::get(T);
if (isUndef)
return UndefValue::get(T);
+ if (isSplatFP)
+ return ConstantFP::get(C->getContext(), T->getElementCount(),
+ cast<ConstantFP>(C)->getValue());
+ if (isSplatInt)
+ return ConstantInt::get(C->getContext(), T->getElementCount(),
+ cast<ConstantInt>(C)->getValue());
// Check to see if all of the elements are ConstantFP or ConstantInt and if
// the element type is compatible with ConstantDataVector. If so, use it.
@@ -1384,6 +1448,16 @@ Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {
Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
if (!EC.isScalable()) {
+ // Maintain special handling of zero.
+ if (!V->isNullValue()) {
+ if (UseConstantIntForFixedLengthSplat && isa<ConstantInt>(V))
+ return ConstantInt::get(V->getContext(), EC,
+ cast<ConstantInt>(V)->getValue());
+ if (UseConstantFPForFixedLengthSplat && isa<ConstantFP>(V))
+ return ConstantFP::get(V->getContext(), EC,
+ cast<ConstantFP>(V)->getValue());
+ }
+
// If this splat is compatible with ConstantDataVector, use it instead of
// ConstantVector.
if ((isa<ConstantFP>(V) || isa<ConstantInt>(V)) &&
@@ -1394,6 +1468,16 @@ Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
return get(Elts);
}
+ // Maintain special handling of zero.
+ if (!V->isNullValue()) {
+ if (UseConstantIntForScalableSplat && isa<ConstantInt>(V))
+ return ConstantInt::get(V->getContext(), EC,
+ cast<ConstantInt>(V)->getValue());
+ if (UseConstantFPForScalableSplat && isa<ConstantFP>(V))
+ return ConstantFP::get(V->getContext(), EC,
+ cast<ConstantFP>(V)->getValue());
+ }
+
Type *VTy = VectorType::get(V->getType(), EC);
if (V->isNullValue())
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index eb18be5..389bac4 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -64,6 +64,9 @@ void DbgRecord::deleteRecord() {
case ValueKind:
delete cast<DPValue>(this);
return;
+ case LabelKind:
+ delete cast<DPLabel>(this);
+ return;
}
llvm_unreachable("unsupported DbgRecord kind");
}
@@ -73,6 +76,9 @@ void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
case ValueKind:
cast<DPValue>(this)->print(O, IsForDebug);
return;
+ case LabelKind:
+ cast<DPLabel>(this)->print(O, IsForDebug);
+ return;
};
llvm_unreachable("unsupported DbgRecord kind");
}
@@ -83,6 +89,9 @@ void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,
case ValueKind:
cast<DPValue>(this)->print(O, MST, IsForDebug);
return;
+ case LabelKind:
+ cast<DPLabel>(this)->print(O, MST, IsForDebug);
+ return;
};
llvm_unreachable("unsupported DbgRecord kind");
}
@@ -93,16 +102,23 @@ bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
switch (RecordKind) {
case ValueKind:
return cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R));
+ case LabelKind:
+ return cast<DPLabel>(this)->getLabel() == cast<DPLabel>(R).getLabel();
};
llvm_unreachable("unsupported DbgRecord kind");
}
bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
- if (RecordKind != R.RecordKind)
- return false;
+ return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R);
+}
+
+DbgInfoIntrinsic *
+DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
switch (RecordKind) {
case ValueKind:
- return cast<DPValue>(this)->isEquivalentTo(*cast<DPValue>(&R));
+ return cast<DPValue>(this)->createDebugIntrinsic(M, InsertBefore);
+ case LabelKind:
+ return cast<DPLabel>(this)->createDebugIntrinsic(M, InsertBefore);
};
llvm_unreachable("unsupported DbgRecord kind");
}
@@ -307,12 +323,16 @@ DbgRecord *DbgRecord::clone() const {
switch (RecordKind) {
case ValueKind:
return cast<DPValue>(this)->clone();
+ case LabelKind:
+ return cast<DPLabel>(this)->clone();
};
llvm_unreachable("unsupported DbgRecord kind");
}
DPValue *DPValue::clone() const { return new DPValue(*this); }
+DPLabel *DPLabel::clone() const { return new DPLabel(Label, getDebugLoc()); }
+
DbgVariableIntrinsic *
DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
[[maybe_unused]] DICompileUnit *Unit =
@@ -368,6 +388,20 @@ DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
return DVI;
}
+DbgLabelInst *DPLabel::createDebugIntrinsic(Module *M,
+ Instruction *InsertBefore) const {
+ auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label);
+ Value *Args[] = {
+ MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())};
+ DbgLabelInst *DbgLabel = cast<DbgLabelInst>(
+ CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args));
+ DbgLabel->setTailCall();
+ DbgLabel->setDebugLoc(getDebugLoc());
+ if (InsertBefore)
+ DbgLabel->insertBefore(InsertBefore);
+ return DbgLabel;
+}
+
Value *DPValue::getAddress() const {
auto *MD = getRawAddress();
if (auto *V = dyn_cast<ValueAsMetadata>(MD))
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index ce0df53..fc5c9b2 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -3525,6 +3525,7 @@ CastInst *CastInst::CreateFPCast(Value *C, Type *Ty,
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
+ assert((C->getType() == Ty || SrcBits != DstBits) && "Invalid cast");
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 15c90a4..a0bf9ca 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -119,7 +119,9 @@ LLVMContextImpl::~LLVMContextImpl() {
IntZeroConstants.clear();
IntOneConstants.clear();
IntConstants.clear();
+ IntSplatConstants.clear();
FPConstants.clear();
+ FPSplatConstants.clear();
CDSConstants.clear();
// Destroy attribute node lists.
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 6a20291..2ee1080 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1488,8 +1488,12 @@ public:
DenseMap<unsigned, std::unique_ptr<ConstantInt>> IntZeroConstants;
DenseMap<unsigned, std::unique_ptr<ConstantInt>> IntOneConstants;
DenseMap<APInt, std::unique_ptr<ConstantInt>> IntConstants;
+ DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
+ IntSplatConstants;
DenseMap<APFloat, std::unique_ptr<ConstantFP>> FPConstants;
+ DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
+ FPSplatConstants;
FoldingSet<AttributeImpl> AttrsSet;
FoldingSet<AttributeListImpl> AttrsLists;