[DebugInfo] Refactoring DIType::setFlags to DIType::cloneWithFlags, NFC

and using the latter in DIBuilder::createArtificialType and
DIBuilder::createObjectPointerType methods as well as introducing
mirroring DISubprogram::cloneWithFlags and
DIBuilder::createArtificialSubprogram methods.

The primary goal here is to add createArtificialSubprogram to support
a pass downstream while keeping the method consistent with the
existing ones and making sure we don't encourage changing already
created DI-nodes.

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D47615

llvm-svn: 333806
This commit is contained in:
Roman Tereshin 2018-06-01 23:15:09 +00:00
parent 4b3701a7a7
commit cf88ffaaf9
6 changed files with 92 additions and 23 deletions

View File

@ -678,8 +678,7 @@ LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder,
LLVMMetadataRef Ty);
/**
* Create a new DIType* with the "object pointer"
* flag set.
* Create a uniqued DIType* clone with FlagObjectPointer and FlagArtificial set.
* \param Builder The DIBuilder.
* \param Type The underlying type to which this pointer points.
*/
@ -851,7 +850,7 @@ LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder,
const char *UniqueIdentifier, size_t UniqueIdentifierLen);
/**
* Create a new DIType* with "artificial" flag set.
* Create a uniqued DIType* clone with FlagArtificial set.
* \param Builder The DIBuilder.
* \param Type The underlying type.
*/

View File

@ -515,12 +515,15 @@ namespace llvm {
DINode::DIFlags Flags = DINode::FlagZero,
unsigned CC = 0);
/// Create a new DIType* with "artificial" flag set.
DIType *createArtificialType(DIType *Ty);
/// Create a distinct clone of \p SP with FlagArtificial set.
static DISubprogram *createArtificialSubprogram(DISubprogram *SP);
/// Create a new DIType* with the "object pointer"
/// flag set.
DIType *createObjectPointerType(DIType *Ty);
/// Create a uniqued clone of \p Ty with FlagArtificial set.
static DIType *createArtificialType(DIType *Ty);
/// Create a uniqued clone of \p Ty with FlagObjectPointer and
/// FlagArtificial set.
static DIType *createObjectPointerType(DIType *Ty);
/// Create a permanent forward-declared type.
DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,

View File

@ -679,9 +679,11 @@ public:
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
void setFlags(DIFlags NewFlags) {
assert(!isUniqued() && "Cannot set flags on uniqued nodes");
Flags = NewFlags;
/// Returns a new temporary DIType with updated Flags
TempDIType cloneWithFlags(DIFlags NewFlags) const {
auto NewTy = clone();
NewTy->Flags = NewFlags;
return NewTy;
}
bool isPrivate() const {
@ -1679,6 +1681,13 @@ public:
TempDISubprogram clone() const { return cloneImpl(); }
/// Returns a new temporary DISubprogram with updated Flags
TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
auto NewSP = clone();
NewSP->Flags = NewFlags;
return NewSP;
}
public:
unsigned getLine() const { return Line; }
unsigned getVirtuality() const { return Virtuality; }

View File

@ -535,10 +535,14 @@ DICompositeType *DIBuilder::createVectorType(uint64_t Size,
return R;
}
static DIType *createTypeWithFlags(LLVMContext &Context, DIType *Ty,
DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) {
auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial);
return MDNode::replaceWithDistinct(std::move(NewSP));
}
static DIType *createTypeWithFlags(const DIType *Ty,
DINode::DIFlags FlagsToSet) {
auto NewTy = Ty->clone();
NewTy->setFlags(NewTy->getFlags() | FlagsToSet);
auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet);
return MDNode::replaceWithUniqued(std::move(NewTy));
}
@ -546,7 +550,7 @@ DIType *DIBuilder::createArtificialType(DIType *Ty) {
// FIXME: Restrict this to the nodes where it's valid.
if (Ty->isArtificial())
return Ty;
return createTypeWithFlags(VMContext, Ty, DINode::FlagArtificial);
return createTypeWithFlags(Ty, DINode::FlagArtificial);
}
DIType *DIBuilder::createObjectPointerType(DIType *Ty) {
@ -554,7 +558,7 @@ DIType *DIBuilder::createObjectPointerType(DIType *Ty) {
if (Ty->isObjectPointer())
return Ty;
DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial;
return createTypeWithFlags(VMContext, Ty, Flags);
return createTypeWithFlags(Ty, Flags);
}
void DIBuilder::retainType(DIScope *T) {

View File

@ -459,6 +459,62 @@ TEST_F(IRBuilderTest, DIBuilder) {
EXPECT_TRUE(verifyModule(*M));
}
TEST_F(IRBuilderTest, createArtificialSubprogram) {
IRBuilder<> Builder(BB);
DIBuilder DIB(*M);
auto File = DIB.createFile("main.c", "/");
auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "clang",
/*isOptimized=*/true, /*Flags=*/"",
/*Runtime Version=*/0);
auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
auto SP = DIB.createFunction(CU, "foo", /*LinkageName=*/"", File,
/*LineNo=*/1, Type, /*isLocalToUnit=*/false,
/*isDefinition=*/true, /*ScopeLine=*/2,
DINode::FlagZero, /*isOptimized=*/true);
EXPECT_TRUE(SP->isDistinct());
F->setSubprogram(SP);
AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
ReturnInst *R = Builder.CreateRetVoid();
I->setDebugLoc(DebugLoc::get(3, 2, SP));
R->setDebugLoc(DebugLoc::get(4, 2, SP));
DIB.finalize();
EXPECT_FALSE(verifyModule(*M));
Function *G = Function::Create(F->getFunctionType(),
Function::ExternalLinkage, "", M.get());
BasicBlock *GBB = BasicBlock::Create(Ctx, "", G);
Builder.SetInsertPoint(GBB);
I->removeFromParent();
Builder.Insert(I);
Builder.CreateRetVoid();
EXPECT_FALSE(verifyModule(*M));
DISubprogram *GSP = DIBuilder::createArtificialSubprogram(F->getSubprogram());
EXPECT_EQ(SP->getFile(), GSP->getFile());
EXPECT_EQ(SP->getType(), GSP->getType());
EXPECT_EQ(SP->getLine(), GSP->getLine());
EXPECT_EQ(SP->getScopeLine(), GSP->getScopeLine());
EXPECT_TRUE(GSP->isDistinct());
G->setSubprogram(GSP);
EXPECT_TRUE(verifyModule(*M));
auto *InlinedAtNode =
DILocation::getDistinct(Ctx, GSP->getScopeLine(), 0, GSP);
DebugLoc DL = I->getDebugLoc();
DenseMap<const MDNode *, MDNode *> IANodes;
auto IA = DebugLoc::appendInlinedAt(DL, InlinedAtNode, Ctx, IANodes);
auto NewDL = DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(), IA);
I->setDebugLoc(NewDL);
EXPECT_FALSE(verifyModule(*M));
EXPECT_EQ("foo", SP->getName());
EXPECT_EQ("foo", GSP->getName());
EXPECT_FALSE(SP->isArtificial());
EXPECT_TRUE(GSP->isArtificial());
}
TEST_F(IRBuilderTest, InsertExtractElement) {
IRBuilder<> Builder(BB);

View File

@ -1051,7 +1051,7 @@ TEST_F(DITypeTest, clone) {
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
}
TEST_F(DITypeTest, setFlags) {
TEST_F(DITypeTest, cloneWithFlags) {
// void (void)
Metadata *TypesOps[] = {nullptr};
Metadata *Types = MDTuple::get(Context, TypesOps);
@ -1059,17 +1059,15 @@ TEST_F(DITypeTest, setFlags) {
DIType *D =
DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types);
EXPECT_EQ(DINode::FlagZero, D->getFlags());
D->setFlags(DINode::FlagRValueReference);
EXPECT_EQ(DINode::FlagRValueReference, D->getFlags());
D->setFlags(DINode::FlagZero);
TempDIType D2 = D->cloneWithFlags(DINode::FlagRValueReference);
EXPECT_EQ(DINode::FlagRValueReference, D2->getFlags());
EXPECT_EQ(DINode::FlagZero, D->getFlags());
TempDIType T =
DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types);
EXPECT_EQ(DINode::FlagZero, T->getFlags());
T->setFlags(DINode::FlagRValueReference);
EXPECT_EQ(DINode::FlagRValueReference, T->getFlags());
T->setFlags(DINode::FlagZero);
TempDIType T2 = T->cloneWithFlags(DINode::FlagRValueReference);
EXPECT_EQ(DINode::FlagRValueReference, T2->getFlags());
EXPECT_EQ(DINode::FlagZero, T->getFlags());
}