Subzero. Fixes memory leaks.
Adds named constructors to initialzers. Removes destructor from Inst.
BUG= None
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1181013016.
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index f3b04eb..72c9120 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -77,11 +77,12 @@
constexpr char BlockNameGlobalPrefix[] = ".L$profiler$block_name$";
constexpr char BlockStatsGlobalPrefix[] = ".L$profiler$block_info$";
-VariableDeclaration *nodeNameDeclaration(const IceString &NodeAsmName) {
- VariableDeclaration *Var = VariableDeclaration::create();
+VariableDeclaration *nodeNameDeclaration(GlobalContext *Ctx,
+ const IceString &NodeAsmName) {
+ VariableDeclaration *Var = VariableDeclaration::create(Ctx);
Var->setName(BlockNameGlobalPrefix + NodeAsmName);
Var->setIsConstant(true);
- Var->addInitializer(new VariableDeclaration::DataInitializer(
+ Var->addInitializer(VariableDeclaration::DataInitializer::create(
NodeAsmName.data(), NodeAsmName.size() + 1));
const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
Var->setAlignment(Int64ByteSize); // Wasteful, 32-bit could use 4 bytes.
@@ -89,20 +90,20 @@
}
VariableDeclaration *
-blockProfilingInfoDeclaration(const IceString &NodeAsmName,
+blockProfilingInfoDeclaration(GlobalContext *Ctx, const IceString &NodeAsmName,
VariableDeclaration *NodeNameDeclaration) {
- VariableDeclaration *Var = VariableDeclaration::create();
+ VariableDeclaration *Var = VariableDeclaration::create(Ctx);
Var->setName(BlockStatsGlobalPrefix + NodeAsmName);
const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
- Var->addInitializer(new VariableDeclaration::ZeroInitializer(Int64ByteSize));
+ Var->addInitializer(
+ VariableDeclaration::ZeroInitializer::create(Int64ByteSize));
const RelocOffsetT NodeNameDeclarationOffset = 0;
- Var->addInitializer(new VariableDeclaration::RelocInitializer(
+ Var->addInitializer(VariableDeclaration::RelocInitializer::create(
NodeNameDeclaration, NodeNameDeclarationOffset));
Var->setAlignment(Int64ByteSize);
return Var;
}
-
} // end of anonymous namespace
void Cfg::profileBlocks() {
@@ -111,9 +112,9 @@
for (CfgNode *Node : Nodes) {
IceString NodeAsmName = Node->getAsmName();
- GlobalInits->push_back(nodeNameDeclaration(NodeAsmName));
+ GlobalInits->push_back(nodeNameDeclaration(Ctx, NodeAsmName));
GlobalInits->push_back(
- blockProfilingInfoDeclaration(NodeAsmName, GlobalInits->back()));
+ blockProfilingInfoDeclaration(Ctx, NodeAsmName, GlobalInits->back()));
Node->profileExecutionCount(GlobalInits->back());
}
}
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index 6b83b15..baa8eeb 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -754,7 +754,7 @@
if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) {
assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) &&
(cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8));
- Global.addInitializer(new Ice::VariableDeclaration::DataInitializer(
+ Global.addInitializer(Ice::VariableDeclaration::DataInitializer::create(
CDA->getRawDataValues().data(), CDA->getNumElements()));
return;
}
@@ -763,8 +763,8 @@
if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) {
assert(!HasOffset && isa<IntegerType>(AT->getElementType()) &&
(cast<IntegerType>(AT->getElementType())->getBitWidth() == 8));
- Global.addInitializer(
- new Ice::VariableDeclaration::ZeroInitializer(AT->getNumElements()));
+ Global.addInitializer(Ice::VariableDeclaration::ZeroInitializer::create(
+ AT->getNumElements()));
} else {
llvm_unreachable("Unhandled constant aggregate zero type");
}
@@ -786,7 +786,7 @@
const Ice::GlobalDeclaration *Addr =
getConverter().getGlobalDeclaration(GV);
Global.addInitializer(
- new Ice::VariableDeclaration::RelocInitializer(Addr, Offset));
+ Ice::VariableDeclaration::RelocInitializer::create(Addr, Offset));
return;
}
default:
@@ -867,7 +867,7 @@
Converter.convertToIceType(FuncType->getParamType(I)));
}
FunctionDeclaration *IceFunc = FunctionDeclaration::create(
- Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
+ Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty());
IceFunc->setName(Func.getName());
GlobalDeclarationMap[&Func] = IceFunc;
}
@@ -876,7 +876,7 @@
E = Mod->global_end();
I != E; ++I) {
const GlobalVariable *GV = I;
- VariableDeclaration *Var = VariableDeclaration::create();
+ VariableDeclaration *Var = VariableDeclaration::create(Ctx);
Var->setName(GV->getName());
Var->setAlignment(GV->getAlignment());
Var->setIsConstant(GV->isConstant());
diff --git a/src/IceDefs.h b/src/IceDefs.h
index 64e70de..4531275 100644
--- a/src/IceDefs.h
+++ b/src/IceDefs.h
@@ -93,6 +93,46 @@
return false;
}
+// makeUnique should be used when memory is expected to be allocated from the
+// heap (as opposed to allocated from some Allocator.) It is intended to be used
+// instead of new.
+//
+// The expected usage is as follows
+//
+// class MyClass {
+// public:
+// static std::unique_ptr<MyClass> create(<ctor_args>) {
+// return makeUnique<MyClass>(<ctor_args>);
+// }
+//
+// private:
+// ENABLE_MAKE_UNIQUE;
+//
+// MyClass(<ctor_args>) ...
+// }
+//
+// ENABLE_MAKE_UNIQUE is a trick that is necessary if MyClass' ctor is private.
+// Private ctors are highly encouraged when you're writing a class that you'd
+// like to have allocated with makeUnique as it would prevent users from
+// declaring stack allocated variables.
+namespace Internal {
+struct MakeUniqueEnabler {
+ template <class T, class... Args>
+ static std::unique_ptr<T> create(Args &&... TheArgs) {
+ std::unique_ptr<T> Unique(new T(std::forward<Args>(TheArgs)...));
+ return Unique;
+ }
+};
+} // end of namespace Internal
+
+template <class T, class... Args>
+static std::unique_ptr<T> makeUnique(Args &&... TheArgs) {
+ return ::Ice::Internal::MakeUniqueEnabler::create<T>(
+ std::forward<Args>(TheArgs)...);
+}
+
+#define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler
+
typedef std::string IceString;
typedef llvm::ilist<Inst> InstList;
// Ideally PhiList would be llvm::ilist<InstPhi>, and similar for
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp
index d24144c..0549754 100644
--- a/src/IceELFObjectWriter.cpp
+++ b/src/IceELFObjectWriter.cpp
@@ -386,12 +386,12 @@
Section->setSize(Section->getCurrentSize() + SymbolSize);
} else {
assert(ST != BSS);
- for (VariableDeclaration::Initializer *Init : Var->getInitializers()) {
+ for (const std::unique_ptr<VariableDeclaration::Initializer> &Init :
+ Var->getInitializers()) {
switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: {
- const auto Data =
- llvm::cast<VariableDeclaration::DataInitializer>(Init)
- ->getContents();
+ const auto Data = llvm::cast<VariableDeclaration::DataInitializer>(
+ Init.get())->getContents();
Section->appendData(Str, llvm::StringRef(Data.data(), Data.size()));
break;
}
@@ -400,7 +400,7 @@
break;
case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto Reloc =
- llvm::cast<VariableDeclaration::RelocInitializer>(Init);
+ llvm::cast<VariableDeclaration::RelocInitializer>(Init.get());
AssemblerFixup NewFixup;
NewFixup.set_position(Section->getCurrentSize());
NewFixup.set_kind(RelocationKind);
diff --git a/src/IceELFSection.h b/src/IceELFSection.h
index ecbf555..a79a9fb 100644
--- a/src/IceELFSection.h
+++ b/src/IceELFSection.h
@@ -33,6 +33,8 @@
ELFSection &operator=(const ELFSection &) = delete;
public:
+ virtual ~ELFSection() = default;
+
// Sentinel value for a section number/index for before the final
// section index is actually known. The dummy NULL section will be assigned
// number 0, and it is referenced by the dummy 0-th symbol in the symbol
@@ -81,8 +83,6 @@
template <bool IsELF64> void writeHeader(ELFStreamer &Str);
protected:
- ~ELFSection() = default;
-
// Name of the section in convenient string form (instead of a index
// into the Section Header String Table, which is not known till later).
const IceString Name;
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 187ebd5..38d1457 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -223,8 +223,7 @@
/*MaxSize=*/Flags.getNumTranslationThreads()),
// EmitQ is allowed unlimited size.
EmitQ(/*Sequential=*/Flags.isSequential()),
- DataLowering(TargetDataLowering::createLowering(this)),
- ProfileBlockInfoVarDecl(VariableDeclaration::create()) {
+ DataLowering(TargetDataLowering::createLowering(this)) {
assert(OsDump && "OsDump is not defined for GlobalContext");
assert(OsEmit && "OsEmit is not defined for GlobalContext");
assert(OsError && "OsError is not defined for GlobalContext");
@@ -256,6 +255,11 @@
case FT_Iasm:
break;
}
+
+ // ProfileBlockInfoVarDecl is initialized here because it takes this as a
+ // parameter -- we want to
+ // ensure that at least this' member variables are initialized.
+ ProfileBlockInfoVarDecl = VariableDeclaration::create(this);
ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64));
ProfileBlockInfoVarDecl->setIsConstant(true);
@@ -346,7 +350,7 @@
if (Cfg::isProfileGlobal(*Global)) {
constexpr RelocOffsetT BlockExecutionCounterOffset = 0;
ProfileBlockInfo->addInitializer(
- new VariableDeclaration::RelocInitializer(
+ VariableDeclaration::RelocInitializer::create(
Global, BlockExecutionCounterOffset));
}
}
@@ -387,20 +391,28 @@
if (Flags.getDisableTranslation())
return;
- addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl.get());
+ addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl);
DataLowering->lowerGlobals(Globals, SectionSuffix);
+ for (VariableDeclaration *Var : Globals) {
+ Var->discardInitializers();
+ }
Globals.clear();
}
void GlobalContext::lowerProfileData() {
+ // ProfileBlockInfoVarDecl is initialized in the constructor, and will only
+ // ever be nullptr after this method completes. This assertion is a convoluted
+ // way of ensuring lowerProfileData is invoked a single time.
+ assert(ProfileBlockInfoVarDecl != nullptr);
// This adds a 64-bit sentinel entry to the end of our array. For 32-bit
// architectures this will waste 4 bytes.
const SizeT Sizeof64BitNullPtr = typeWidthInBytes(IceType_i64);
ProfileBlockInfoVarDecl->addInitializer(
- new VariableDeclaration::ZeroInitializer(Sizeof64BitNullPtr));
- Globals.push_back(ProfileBlockInfoVarDecl.get());
+ VariableDeclaration::ZeroInitializer::create(Sizeof64BitNullPtr));
+ Globals.push_back(ProfileBlockInfoVarDecl);
constexpr char ProfileDataSection[] = "$sz_profiler$";
lowerGlobals(ProfileDataSection);
+ ProfileBlockInfoVarDecl = nullptr;
}
void GlobalContext::emitItems() {
@@ -649,6 +661,12 @@
GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(AllThreadContexts);
+ LockedPtr<DestructorArray> Dtors = getDestructors();
+ // Destructors are invoked in the opposite object construction order.
+ for (auto DtorIter = Dtors->crbegin(); DtorIter != Dtors->crend();
+ ++DtorIter) {
+ (*DtorIter)();
+ }
}
// TODO(stichnot): Consider adding thread-local caches of constant
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index 7adde9f..8854f69 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -16,8 +16,11 @@
#define SUBZERO_SRC_ICEGLOBALCONTEXT_H
#include <array>
+#include <functional>
#include <mutex>
#include <thread>
+#include <type_traits>
+#include <vector>
#include "IceDefs.h"
#include "IceClFlags.h"
@@ -211,8 +214,24 @@
return getFlags().getDisableIRGeneration();
}
- // Allocate data of type T using the global allocator.
- template <typename T> T *allocate() { return getAllocator()->Allocate<T>(); }
+ // Allocate data of type T using the global allocator. We allow entities
+ // allocated from this global allocator to be either trivially or
+ // non-trivially destructible. We optimize the case when T is trivially
+ // destructible by not registering a destructor. Destructors will be invoked
+ // during GlobalContext destruction in the reverse object creation order.
+ template <typename T>
+ typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type *
+ allocate() {
+ return getAllocator()->Allocate<T>();
+ }
+
+ template <typename T>
+ typename std::enable_if<!std::is_trivially_destructible<T>::value, T>::type *
+ allocate() {
+ T *Ret = getAllocator()->Allocate<T>();
+ getDestructors()->emplace_back([Ret]() { Ret->~T(); });
+ return Ret;
+ }
const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; }
@@ -392,8 +411,9 @@
// until the queue is empty.
void emitItems();
- // Uses DataLowering to lower Globals. As a side effect, clears the Globals
- // array.
+ // Uses DataLowering to lower Globals. Side effects:
+ // - discards the initializer list for the global variable in Globals.
+ // - clears the Globals array.
void lowerGlobals(const IceString &SectionSuffix);
// Lowers the profile information.
@@ -417,12 +437,19 @@
private:
// Try to ensure mutexes are allocated on separate cache lines.
+ // Destructors collaborate with Allocator
ICE_CACHELINE_BOUNDARY;
// Managed by getAllocator()
GlobalLockType AllocLock;
ArenaAllocator<> Allocator;
ICE_CACHELINE_BOUNDARY;
+ // Managed by getDestructors()
+ typedef std::vector<std::function<void()>> DestructorArray;
+ GlobalLockType DestructorsLock;
+ DestructorArray Destructors;
+
+ ICE_CACHELINE_BOUNDARY;
// Managed by getConstantPool()
GlobalLockType ConstPoolLock;
std::unique_ptr<ConstantPool> ConstPool;
@@ -470,7 +497,7 @@
// TODO(jpp): move to EmitterContext.
VariableDeclarationList Globals;
// TODO(jpp): move to EmitterContext.
- std::unique_ptr<VariableDeclaration> ProfileBlockInfoVarDecl;
+ VariableDeclaration *ProfileBlockInfoVarDecl;
LockedPtr<ArenaAllocator<>> getAllocator() {
return LockedPtr<ArenaAllocator<>>(&Allocator, &AllocLock);
@@ -484,6 +511,9 @@
LockedPtr<TimerList> getTimers() {
return LockedPtr<TimerList>(&Timers, &TimerLock);
}
+ LockedPtr<DestructorArray> getDestructors() {
+ return LockedPtr<DestructorArray>(&Destructors, &DestructorsLock);
+ }
void accumulateGlobals(std::unique_ptr<VariableDeclarationList> Globls) {
if (Globls != nullptr)
diff --git a/src/IceGlobalInits.cpp b/src/IceGlobalInits.cpp
index c9bdf99..2ee5e62 100644
--- a/src/IceGlobalInits.cpp
+++ b/src/IceGlobalInits.cpp
@@ -60,12 +60,6 @@
namespace Ice {
-FunctionDeclaration *FunctionDeclaration::create(
- const FuncSigType &Signature, llvm::CallingConv::ID CallingConv,
- llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) {
- return new FunctionDeclaration(Signature, CallingConv, Linkage, IsProto);
-}
-
void FunctionDeclaration::dumpType(Ostream &Stream) const {
if (!ALLOW_DUMP)
return;
@@ -92,23 +86,15 @@
Stream << ")";
}
-VariableDeclaration *VariableDeclaration::create() {
- return new VariableDeclaration();
-}
-
-VariableDeclaration::~VariableDeclaration() {
- llvm::DeleteContainerPointers(Initializers);
-}
-
void VariableDeclaration::dumpType(Ostream &Stream) const {
if (!ALLOW_DUMP)
return;
- if (Initializers.size() == 1) {
- Initializers.front()->dumpType(Stream);
+ if (Initializers->size() == 1) {
+ Initializers->front()->dumpType(Stream);
} else {
Stream << "<{ ";
bool IsFirst = true;
- for (Initializer *Init : Initializers) {
+ for (const std::unique_ptr<Initializer> &Init : *Initializers) {
if (IsFirst) {
IsFirst = false;
} else {
@@ -130,13 +116,13 @@
Stream << " " << (IsConstant ? "constant" : "global") << " ";
// Add initializer.
- if (Initializers.size() == 1) {
- Initializers.front()->dump(Stream);
+ if (Initializers->size() == 1) {
+ Initializers->front()->dump(Stream);
} else {
dumpType(Stream);
Stream << " <{ ";
bool IsFirst = true;
- for (Initializer *Init : Initializers) {
+ for (const std::unique_ptr<Initializer> &Init : *Initializers) {
if (IsFirst) {
IsFirst = false;
} else {
diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h
index 824f704..cd66500 100644
--- a/src/IceGlobalInits.h
+++ b/src/IceGlobalInits.h
@@ -17,8 +17,12 @@
#ifndef SUBZERO_SRC_ICEGLOBALINITS_H
#define SUBZERO_SRC_ICEGLOBALINITS_H
+#include <memory>
+#include <utility>
+
+#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" // for NaClBitcodeRecord.
#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes
+#include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes.
#include "IceDefs.h"
#include "IceTypes.h"
@@ -95,11 +99,14 @@
FunctionDeclaration &operator=(const FunctionDeclaration &) = delete;
public:
- static FunctionDeclaration *create(const FuncSigType &Signature,
+ static FunctionDeclaration *create(GlobalContext *Context,
+ const FuncSigType &Signature,
llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage,
- bool IsProto);
- ~FunctionDeclaration() final {}
+ bool IsProto) {
+ return new (Context->allocate<FunctionDeclaration>())
+ FunctionDeclaration(Signature, CallingConv, Linkage, IsProto);
+ }
const FuncSigType &getSignature() const { return Signature; }
llvm::CallingConv::ID getCallingConv() const { return CallingConv; }
// isProto implies that there isn't a (local) definition for the function.
@@ -167,21 +174,11 @@
DataInitializer &operator=(const DataInitializer &) = delete;
public:
- template <class IntContainer>
- DataInitializer(const IntContainer &Values)
- : Initializer(DataInitializerKind), Contents(Values.size()) {
- size_t i = 0;
- for (auto &V : Values) {
- Contents[i] = static_cast<int8_t>(V);
- ++i;
- }
+ template <class... Args>
+ static std::unique_ptr<DataInitializer> create(Args &&... TheArgs) {
+ return makeUnique<DataInitializer>(std::forward<Args>(TheArgs)...);
}
- DataInitializer(const char *Str, size_t StrLen)
- : Initializer(DataInitializerKind), Contents(StrLen) {
- for (size_t i = 0; i < StrLen; ++i)
- Contents[i] = Str[i];
- }
- ~DataInitializer() override {}
+
const DataVecType &getContents() const { return Contents; }
SizeT getNumBytes() const final { return Contents.size(); }
void dump(GlobalContext *Ctx, Ostream &Stream) const final;
@@ -190,6 +187,20 @@
}
private:
+ ENABLE_MAKE_UNIQUE;
+
+ DataInitializer(const llvm::NaClBitcodeRecord::RecordVector &Values)
+ : Initializer(DataInitializerKind), Contents(Values.size()) {
+ for (SizeT I = 0; I < Values.size(); ++I)
+ Contents[I] = static_cast<int8_t>(Values[I]);
+ }
+
+ DataInitializer(const char *Str, size_t StrLen)
+ : Initializer(DataInitializerKind), Contents(StrLen) {
+ for (size_t i = 0; i < StrLen; ++i)
+ Contents[i] = Str[i];
+ }
+
// The byte contents of the data initializer.
DataVecType Contents;
};
@@ -200,9 +211,9 @@
ZeroInitializer &operator=(const ZeroInitializer &) = delete;
public:
- explicit ZeroInitializer(SizeT Size)
- : Initializer(ZeroInitializerKind), Size(Size) {}
- ~ZeroInitializer() override {}
+ static std::unique_ptr<ZeroInitializer> create(SizeT Size) {
+ return makeUnique<ZeroInitializer>(Size);
+ }
SizeT getNumBytes() const final { return Size; }
void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const Initializer *Z) {
@@ -210,6 +221,11 @@
}
private:
+ ENABLE_MAKE_UNIQUE;
+
+ explicit ZeroInitializer(SizeT Size)
+ : Initializer(ZeroInitializerKind), Size(Size) {}
+
// The number of bytes to be zero initialized.
SizeT Size;
};
@@ -220,10 +236,11 @@
RelocInitializer &operator=(const RelocInitializer &) = delete;
public:
- RelocInitializer(const GlobalDeclaration *Declaration, RelocOffsetT Offset)
- : Initializer(RelocInitializerKind), Declaration(Declaration),
- Offset(Offset) {}
- ~RelocInitializer() override {}
+ static std::unique_ptr<RelocInitializer>
+ create(const GlobalDeclaration *Declaration, RelocOffsetT Offset) {
+ return makeUnique<RelocInitializer>(Declaration, Offset);
+ }
+
RelocOffsetT getOffset() const { return Offset; }
const GlobalDeclaration *getDeclaration() const { return Declaration; }
SizeT getNumBytes() const final { return RelocAddrSize; }
@@ -234,34 +251,40 @@
}
private:
- // The global declaration used in the relocation.
+ ENABLE_MAKE_UNIQUE;
+
+ RelocInitializer(const GlobalDeclaration *Declaration, RelocOffsetT Offset)
+ : Initializer(RelocInitializerKind), Declaration(Declaration),
+ Offset(Offset) {} // The global declaration used in the relocation.
+
const GlobalDeclaration *Declaration;
// The offset to add to the relocation.
const RelocOffsetT Offset;
};
/// Models the list of initializers.
- typedef std::vector<Initializer *> InitializerListType;
+ typedef std::vector<std::unique_ptr<Initializer>> InitializerListType;
- static VariableDeclaration *create();
- ~VariableDeclaration() final;
+ static VariableDeclaration *create(GlobalContext *Context) {
+ return new (Context->allocate<VariableDeclaration>()) VariableDeclaration();
+ }
- const InitializerListType &getInitializers() const { return Initializers; }
+ const InitializerListType &getInitializers() const { return *Initializers; }
bool getIsConstant() const { return IsConstant; }
void setIsConstant(bool NewValue) { IsConstant = NewValue; }
uint32_t getAlignment() const { return Alignment; }
void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
- bool hasInitializer() const { return !Initializers.empty(); }
+ bool hasInitializer() const { return HasInitializer; }
bool hasNonzeroInitializer() const {
- return !(Initializers.size() == 1 &&
- llvm::isa<ZeroInitializer>(Initializers[0]));
+ return !(Initializers->size() == 1 &&
+ llvm::isa<ZeroInitializer>((*Initializers)[0].get()));
}
/// Returns the number of bytes for the initializer of the global
/// address.
SizeT getNumBytes() const {
SizeT Count = 0;
- for (Initializer *Init : Initializers) {
+ for (const std::unique_ptr<Initializer> &Init : *Initializers) {
Count += Init->getNumBytes();
}
return Count;
@@ -269,8 +292,9 @@
/// Adds Initializer to the list of initializers. Takes ownership of
/// the initializer.
- void addInitializer(Initializer *Initializer) {
- Initializers.push_back(Initializer);
+ void addInitializer(std::unique_ptr<Initializer> Initializer) {
+ Initializers->emplace_back(std::move(Initializer));
+ HasInitializer = true;
}
/// Prints out type for initializer associated with the declaration
@@ -293,9 +317,12 @@
void setSuppressMangling() { ForceSuppressMangling = true; }
+ void discardInitializers() { Initializers = nullptr; }
+
private:
// list of initializers for the declared variable.
- InitializerListType Initializers;
+ std::unique_ptr<InitializerListType> Initializers;
+ bool HasInitializer;
// The alignment of the declared variable.
uint32_t Alignment;
// True if a declared (global) constant.
@@ -306,6 +333,7 @@
VariableDeclaration()
: GlobalDeclaration(VariableDeclarationKind,
llvm::GlobalValue::InternalLinkage),
+ Initializers(new InitializerListType), HasInitializer(false),
Alignment(0), IsConstant(false), ForceSuppressMangling(false) {}
};
diff --git a/src/IceInst.h b/src/IceInst.h
index 84bd83d..2b5adc6 100644
--- a/src/IceInst.h
+++ b/src/IceInst.h
@@ -161,6 +161,9 @@
void dumpDest(const Cfg *Func) const;
virtual bool isRedundantAssign() const { return false; }
+ // TODO(jpp): Insts should not have non-trivial destructors, but they
+ // currently do. This dtor is marked final as a multi-step refactor that
+ // will eventually fix this problem.
virtual ~Inst() = default;
protected:
@@ -229,7 +232,6 @@
void emitIAS(const Cfg * /*Func*/) const override {
llvm_unreachable("emitIAS() called on a non-lowered instruction");
}
- ~InstHighLevel() override {}
};
// Alloca instruction. This captures the size in bytes as getSrc(0),
@@ -254,7 +256,7 @@
private:
InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
Variable *Dest);
- ~InstAlloca() override {}
+
const uint32_t AlignInBytes;
};
@@ -289,7 +291,6 @@
private:
InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
Operand *Source2);
- ~InstArithmetic() override {}
const OpKind Op;
};
@@ -315,7 +316,6 @@
private:
InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
- ~InstAssign() override {}
};
// Branch instruction. This represents both conditional and
@@ -359,7 +359,6 @@
InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
// Unconditional branch
InstBr(Cfg *Func, CfgNode *Target);
- ~InstBr() override {}
CfgNode *TargetFalse; // Doubles as unconditional branch target
CfgNode *TargetTrue; // nullptr if unconditional branch
@@ -399,7 +398,6 @@
HasSideEffects = HasSideEff;
addSource(CallTarget);
}
- ~InstCall() override {}
private:
bool HasTailCall;
@@ -432,7 +430,7 @@
private:
InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
- ~InstCast() override {}
+
const OpKind CastKind;
};
@@ -457,7 +455,6 @@
private:
InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
Operand *Source2);
- ~InstExtractElement() override {}
};
// Floating-point comparison instruction. The source operands are
@@ -487,7 +484,7 @@
private:
InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
Operand *Source2);
- ~InstFcmp() override {}
+
const FCond Condition;
};
@@ -518,7 +515,7 @@
private:
InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
Operand *Source2);
- ~InstIcmp() override {}
+
const ICond Condition;
};
@@ -543,7 +540,6 @@
private:
InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
Operand *Source2, Operand *Source3);
- ~InstInsertElement() override {}
};
// Call to an intrinsic function. The call target is captured as getSrc(0),
@@ -572,7 +568,7 @@
: InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
Inst::IntrinsicCall),
Info(Info) {}
- ~InstIntrinsicCall() override {}
+
const Intrinsics::IntrinsicInfo Info;
};
@@ -595,7 +591,6 @@
private:
InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
- ~InstLoad() override {}
};
// Phi instruction. For incoming edge I, the node is Labels[I] and
@@ -624,7 +619,6 @@
Func->deallocateArrayOf<CfgNode *>(Labels);
Inst::destroy(Func);
}
- ~InstPhi() override {}
// Labels[] duplicates the InEdges[] information in the enclosing
// CfgNode, but the Phi instruction is created before InEdges[]
@@ -655,7 +649,6 @@
private:
InstRet(Cfg *Func, Operand *RetValue);
- ~InstRet() override {}
};
// Select instruction. The condition, true, and false operands are captured.
@@ -679,7 +672,6 @@
private:
InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
Operand *Source2);
- ~InstSelect() override {}
};
// Store instruction. The address operand is captured, along with the
@@ -705,7 +697,6 @@
private:
InstStore(Cfg *Func, Operand *Data, Operand *Addr);
- ~InstStore() override {}
};
// Switch instruction. The single source operand is captured as
@@ -745,7 +736,6 @@
Func->deallocateArrayOf<CfgNode *>(Labels);
Inst::destroy(Func);
}
- ~InstSwitch() override {}
CfgNode *LabelDefault;
SizeT NumCases; // not including the default case
@@ -772,7 +762,6 @@
private:
explicit InstUnreachable(Cfg *Func);
- ~InstUnreachable() override {}
};
// BundleLock instruction. There are no operands. Contains an option
@@ -799,7 +788,6 @@
private:
Option BundleOption;
InstBundleLock(Cfg *Func, Option BundleOption);
- ~InstBundleLock() override {}
};
// BundleUnlock instruction. There are no operands.
@@ -821,7 +809,6 @@
private:
explicit InstBundleUnlock(Cfg *Func);
- ~InstBundleUnlock() override {}
};
// FakeDef instruction. This creates a fake definition of a variable,
@@ -853,7 +840,6 @@
private:
InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
- ~InstFakeDef() override {}
};
// FakeUse instruction. This creates a fake use of a variable, to
@@ -877,7 +863,6 @@
private:
InstFakeUse(Cfg *Func, Variable *Src);
- ~InstFakeUse() override {}
};
// FakeKill instruction. This "kills" a set of variables by modeling
@@ -907,7 +892,6 @@
private:
InstFakeKill(Cfg *Func, const Inst *Linked);
- ~InstFakeKill() override {}
// This instruction is ignored if Linked->isDeleted() is true.
const Inst *Linked;
@@ -930,7 +914,6 @@
: Inst(Func, Kind, MaxSrcs, Dest) {
assert(Kind >= Target);
}
- ~InstTarget() override {}
};
bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
diff --git a/src/IceInstARM32.h b/src/IceInstARM32.h
index b9ed01e..2ec1356 100644
--- a/src/IceInstARM32.h
+++ b/src/IceInstARM32.h
@@ -59,7 +59,6 @@
protected:
OperandARM32(OperandKindARM32 Kind, Type Ty)
: Operand(static_cast<OperandKind>(Kind), Ty) {}
- ~OperandARM32() override {}
};
// OperandARM32Mem represents a memory operand in any of the various ARM32
@@ -141,7 +140,7 @@
ConstantInteger32 *ImmOffset, AddrMode Mode);
OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, Variable *Index,
ShiftKind ShiftOp, uint16_t ShiftAmt, AddrMode Mode);
- ~OperandARM32Mem() override {}
+
Variable *Base;
ConstantInteger32 *ImmOffset;
Variable *Index;
@@ -167,7 +166,6 @@
protected:
OperandARM32Flex(OperandKindARM32 Kind, Type Ty) : OperandARM32(Kind, Ty) {}
- ~OperandARM32Flex() override {}
};
// Rotated immediate variant.
@@ -202,7 +200,6 @@
private:
OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt);
- ~OperandARM32FlexImm() override {}
uint32_t Imm;
uint32_t RotateAmt;
@@ -238,7 +235,6 @@
private:
OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, ShiftKind ShiftOp,
Operand *ShiftAmt);
- ~OperandARM32FlexReg() override {}
Variable *Reg;
ShiftKind ShiftOp;
@@ -296,7 +292,7 @@
protected:
InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
: InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
- ~InstARM32() override {}
+
static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) {
return Inst->getKind() == static_cast<InstKind>(MyKind);
}
@@ -377,7 +373,7 @@
: InstARM32Pred(Func, K, 1, Dest, Predicate) {
addSource(Src);
}
- ~InstARM32UnaryopGPR() override {}
+
static const char *Opcode;
};
@@ -423,7 +419,7 @@
addSource(Dest);
addSource(Src);
}
- ~InstARM32TwoAddrGPR() override {}
+
static const char *Opcode;
};
@@ -465,7 +461,6 @@
: InstARM32Pred(Func, K, 1, Dest, Predicate) {
addSource(Source);
}
- ~InstARM32Movlike() override {}
static const char *Opcode;
};
@@ -516,7 +511,7 @@
addSource(Src1);
addSource(Src2);
}
- ~InstARM32ThreeAddrGPR() override {}
+
static const char *Opcode;
bool SetFlags;
};
@@ -602,7 +597,7 @@
private:
InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
CondARM32::Cond Predicate);
- ~InstARM32Br() override {}
+
const CfgNode *TargetTrue;
const CfgNode *TargetFalse;
};
@@ -656,7 +651,6 @@
private:
InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
- ~InstARM32Call() override {}
};
// Integer compare instruction.
@@ -679,7 +673,6 @@
private:
InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2,
CondARM32::Cond Predicate);
- ~InstARM32Cmp() override {}
};
// Load instruction.
@@ -703,7 +696,6 @@
private:
InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem,
CondARM32::Cond Predicate);
- ~InstARM32Ldr() override {}
};
// Multiply Accumulate: d := x * y + a
@@ -728,7 +720,6 @@
private:
InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1,
Variable *Acc, CondARM32::Cond Predicate);
- ~InstARM32Mla() override {}
};
// Pop into a list of GPRs. Technically this can be predicated, but we don't
@@ -749,7 +740,7 @@
private:
InstARM32Pop(Cfg *Func, const VarList &Dests);
- ~InstARM32Pop() override {}
+
VarList Dests;
};
@@ -771,7 +762,6 @@
private:
InstARM32Push(Cfg *Func, const VarList &Srcs);
- ~InstARM32Push() override {}
};
// Ret pseudo-instruction. This is actually a "bx" instruction with
@@ -800,7 +790,6 @@
private:
InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source);
- ~InstARM32Ret() override {}
};
// Store instruction. It's important for liveness that there is no Dest
@@ -825,7 +814,6 @@
private:
InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
CondARM32::Cond Predicate);
- ~InstARM32Str() override {}
};
// Unsigned Multiply Long: d.lo, d.hi := x * y
@@ -850,7 +838,7 @@
private:
InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0,
Variable *Src1, CondARM32::Cond Predicate);
- ~InstARM32Umull() override {}
+
Variable *DestHi;
};
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index ec8c39d..d64952b 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -45,7 +45,6 @@
protected:
OperandX8632(OperandKindX8632 Kind, Type Ty)
: Operand(static_cast<OperandKind>(Kind), Ty) {}
- ~OperandX8632() override {}
};
// OperandX8632Mem represents the m32 addressing mode, with optional
@@ -93,7 +92,7 @@
private:
OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
- ~OperandX8632Mem() override {}
+
Variable *Base;
Constant *Offset;
Variable *Index;
@@ -134,14 +133,13 @@
private:
VariableSplit(Cfg *Func, Variable *Var, Portion Part)
- : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
+ : OperandX8632(kSplit, IceType_i32), Var(Var), Part(Part) {
assert(Var->getType() == IceType_f64);
Vars = Func->allocateArrayOf<Variable *>(1);
Vars[0] = Var;
NumVars = 1;
}
- ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); }
- Cfg *Func; // Held only for the destructor.
+
Variable *Var;
Portion Part;
};
@@ -298,7 +296,7 @@
protected:
InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
: InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
- ~InstX8632() override {}
+
static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
return Inst->getKind() == static_cast<InstKind>(MyKind);
}
@@ -359,7 +357,6 @@
InstArithmetic::OpKind Op;
InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
InstArithmetic::OpKind Op, Variable *Beacon);
- ~InstX8632FakeRMW() override {}
};
// InstX8632Label represents an intra-block label that is the target
@@ -418,7 +415,7 @@
private:
InstX8632Label(Cfg *Func, TargetX8632 *Target);
- ~InstX8632Label() override {}
+
SizeT Number; // used for unique label generation.
};
@@ -489,7 +486,7 @@
private:
InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
const InstX8632Label *Label, CondX86::BrCond Condition);
- ~InstX8632Br() override {}
+
CondX86::BrCond Condition;
const CfgNode *TargetTrue;
const CfgNode *TargetFalse;
@@ -559,7 +556,6 @@
private:
InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
- ~InstX8632Call() override {}
};
// Emit a one-operand (GPR) instruction.
@@ -610,7 +606,7 @@
: InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
addSource(SrcDest);
}
- ~InstX8632InplaceopGPR() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
};
@@ -674,7 +670,7 @@
: InstX8632(Func, K, 1, Dest) {
addSource(Src);
}
- ~InstX8632UnaryopGPR() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
};
@@ -724,7 +720,7 @@
: InstX8632(Func, K, 1, Dest) {
addSource(Src);
}
- ~InstX8632UnaryopXmm() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
};
@@ -769,7 +765,7 @@
addSource(Dest);
addSource(Source);
}
- ~InstX8632BinopGPRShift() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
};
@@ -813,7 +809,7 @@
addSource(Dest);
addSource(Source);
}
- ~InstX8632BinopGPR() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
};
@@ -857,7 +853,6 @@
addSource(DestSrc0);
addSource(Src1);
}
- ~InstX8632BinopRMW() override {}
static const char *Opcode;
static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter;
};
@@ -905,7 +900,7 @@
addSource(Dest);
addSource(Source);
}
- ~InstX8632BinopXmm() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
};
@@ -958,7 +953,7 @@
addSource(Dest);
addSource(Source);
}
- ~InstX8632BinopXmmShift() override {}
+
static const char *Opcode;
static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
};
@@ -1005,7 +1000,7 @@
addSource(Source1);
addSource(Source2);
}
- ~InstX8632Ternop() override {}
+
static const char *Opcode;
};
@@ -1052,7 +1047,7 @@
addSource(Source0);
addSource(Source1);
}
- ~InstX8632ThreeAddressop() override {}
+
static const char *Opcode;
};
@@ -1090,7 +1085,6 @@
: InstX8632(Func, K, 1, Dest) {
addSource(Source);
}
- ~InstX8632Movlike() override {}
static const char *Opcode;
};
@@ -1187,7 +1181,6 @@
// with optimizations.
HasSideEffects = Locked;
}
- ~InstX8632Lockable() override {}
};
// Mul instruction - unsigned multiply.
@@ -1209,7 +1202,6 @@
private:
InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
- ~InstX8632Mul() override {}
};
// Shld instruction - shift across a pair of operands.
@@ -1232,7 +1224,6 @@
private:
InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
Variable *Source2);
- ~InstX8632Shld() override {}
};
// Shrd instruction - shift across a pair of operands.
@@ -1255,7 +1246,6 @@
private:
InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
Variable *Source2);
- ~InstX8632Shrd() override {}
};
// Conditional move instruction.
@@ -1278,7 +1268,6 @@
private:
InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::BrCond Cond);
- ~InstX8632Cmov() override {}
CondX86::BrCond Condition;
};
@@ -1304,7 +1293,6 @@
private:
InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::CmppsCond Cond);
- ~InstX8632Cmpps() override {}
CondX86::CmppsCond Condition;
};
@@ -1333,7 +1321,6 @@
private:
InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
Variable *Desired, bool Locked);
- ~InstX8632Cmpxchg() override {}
};
// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
@@ -1362,7 +1349,6 @@
private:
InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
- ~InstX8632Cmpxchg8b() override {}
};
// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
@@ -1390,7 +1376,6 @@
private:
CvtVariant Variant;
InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
- ~InstX8632Cvt() override {}
};
// cmp - Integer compare instruction.
@@ -1411,7 +1396,6 @@
private:
InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
- ~InstX8632Icmp() override {}
};
// ucomiss/ucomisd - floating-point compare instruction.
@@ -1432,7 +1416,6 @@
private:
InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
- ~InstX8632Ucomiss() override {}
};
// UD2 instruction.
@@ -1452,7 +1435,6 @@
private:
explicit InstX8632UD2(Cfg *Func);
- ~InstX8632UD2() override {}
};
// Test instruction.
@@ -1473,7 +1455,6 @@
private:
InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
- ~InstX8632Test() override {}
};
// Mfence instruction.
@@ -1493,7 +1474,6 @@
private:
explicit InstX8632Mfence(Cfg *Func);
- ~InstX8632Mfence() override {}
};
// This is essentially a "mov" instruction with an OperandX8632Mem
@@ -1516,7 +1496,6 @@
private:
InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
- ~InstX8632Store() override {}
};
// This is essentially a vector "mov" instruction with an OperandX8632Mem
@@ -1541,7 +1520,6 @@
private:
InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
- ~InstX8632StoreP() override {}
};
class InstX8632StoreQ : public InstX8632 {
@@ -1562,7 +1540,6 @@
private:
InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
- ~InstX8632StoreQ() override {}
};
// Nop instructions of varying length
@@ -1585,7 +1562,6 @@
private:
InstX8632Nop(Cfg *Func, SizeT Length);
- ~InstX8632Nop() override {}
NopVariant Variant;
};
@@ -1607,7 +1583,6 @@
private:
InstX8632Fld(Cfg *Func, Operand *Src);
- ~InstX8632Fld() override {}
};
// Fstp - store x87 st(0) into memory and pop st(0).
@@ -1627,7 +1602,6 @@
private:
InstX8632Fstp(Cfg *Func, Variable *Dest);
- ~InstX8632Fstp() override {}
};
class InstX8632Pop : public InstX8632 {
@@ -1646,7 +1620,6 @@
private:
InstX8632Pop(Cfg *Func, Variable *Dest);
- ~InstX8632Pop() override {}
};
class InstX8632Push : public InstX8632 {
@@ -1665,7 +1638,6 @@
private:
InstX8632Push(Cfg *Func, Variable *Source);
- ~InstX8632Push() override {}
};
// Ret instruction. Currently only supports the "ret" version that
@@ -1688,7 +1660,6 @@
private:
InstX8632Ret(Cfg *Func, Variable *Source);
- ~InstX8632Ret() override {}
};
// Conditional set-byte instruction.
@@ -1710,7 +1681,6 @@
private:
InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
- ~InstX8632Setcc() override {}
const CondX86::BrCond Condition;
};
@@ -1740,7 +1710,6 @@
private:
InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
- ~InstX8632Xadd() override {}
};
// Exchange instruction. Exchanges the first operand (destination
@@ -1766,7 +1735,6 @@
private:
InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
- ~InstX8632Xchg() override {}
};
// Declare partial template specializations of emit() methods that
diff --git a/src/IceOperand.h b/src/IceOperand.h
index 9e0ff7d..35342fa 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -79,8 +79,6 @@
dump(nullptr, Str);
}
- virtual ~Operand() = default;
-
protected:
Operand(OperandKind Kind, Type Ty) : Ty(Ty), Kind(Kind) {}
@@ -134,7 +132,6 @@
Vars = nullptr;
NumVars = 0;
}
- ~Constant() override {}
// PoolEntryID is an integer that uniquely identifies the constant
// within its constant pool. It is used for building the constant
// pool in the object code and for referencing its entries.
@@ -182,7 +179,6 @@
private:
ConstantPrimitive(Type Ty, PrimType Value, uint32_t PoolEntryID)
: Constant(K, Ty, PoolEntryID), Value(Value) {}
- ~ConstantPrimitive() override {}
const PrimType Value;
};
@@ -271,7 +267,6 @@
bool SuppressMangling, uint32_t PoolEntryID)
: Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset),
Name(Name), SuppressMangling(SuppressMangling) {}
- ~ConstantRelocatable() override {}
const RelocOffsetT Offset; // fixed offset to add
const IceString Name; // optional for debug/dump
bool SuppressMangling;
@@ -308,7 +303,6 @@
private:
ConstantUndef(Type Ty, uint32_t PoolEntryID)
: Constant(kConstUndef, Ty, PoolEntryID) {}
- ~ConstantUndef() override {}
};
// RegWeight is a wrapper for a uint32_t weight value, with a
@@ -514,7 +508,6 @@
Vars[0] = this;
NumVars = 1;
}
- ~Variable() override {}
// Number is unique across all variables, and is used as a
// (bit)vector index for liveness analysis.
const SizeT Number;
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index 35ab024..62c459b 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -512,12 +512,12 @@
Str << MangledName << ":\n";
if (HasNonzeroInitializer) {
- for (VariableDeclaration::Initializer *Init : Var.getInitializers()) {
+ for (const std::unique_ptr<VariableDeclaration::Initializer> &Init :
+ Var.getInitializers()) {
switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: {
- const auto &Data =
- llvm::cast<VariableDeclaration::DataInitializer>(Init)
- ->getContents();
+ const auto &Data = llvm::cast<VariableDeclaration::DataInitializer>(
+ Init.get())->getContents();
for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
}
@@ -528,7 +528,7 @@
break;
case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto *Reloc =
- llvm::cast<VariableDeclaration::RelocInitializer>(Init);
+ llvm::cast<VariableDeclaration::RelocInitializer>(Init.get());
Str << "\t" << getEmit32Directive() << "\t";
Str << Reloc->getDeclaration()->mangleName(Ctx);
if (RelocOffsetT Offset = Reloc->getOffset()) {
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index afe3ebc..11a1f27 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -293,7 +293,8 @@
assert(VariableDeclarations);
assert(VariableDeclarations->empty());
for (size_t i = 0; i < Count; ++i) {
- VariableDeclarations->push_back(Ice::VariableDeclaration::create());
+ VariableDeclarations->push_back(
+ Ice::VariableDeclaration::create(getTranslator().getContext()));
}
}
@@ -904,7 +905,8 @@
GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
: BlockParserBaseClass(BlockID, EnclosingParser),
Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
- DummyGlobalVar(Ice::VariableDeclaration::create()),
+ DummyGlobalVar(
+ Ice::VariableDeclaration::create(getTranslator().getContext())),
CurGlobalVar(DummyGlobalVar) {}
~GlobalsParser() final {}
@@ -1017,7 +1019,7 @@
if (isIRGenerationDisabled())
return;
CurGlobalVar->addInitializer(
- new Ice::VariableDeclaration::ZeroInitializer(Values[0]));
+ Ice::VariableDeclaration::ZeroInitializer::create(Values[0]));
return;
}
case naclbitc::GLOBALVAR_DATA: {
@@ -1027,7 +1029,7 @@
if (isIRGenerationDisabled())
return;
CurGlobalVar->addInitializer(
- new Ice::VariableDeclaration::DataInitializer(Values));
+ Ice::VariableDeclaration::DataInitializer::create(Values));
return;
}
case naclbitc::GLOBALVAR_RELOC: {
@@ -1040,8 +1042,9 @@
Ice::SizeT Offset = 0;
if (Values.size() == 2)
Offset = Values[1];
- CurGlobalVar->addInitializer(new Ice::VariableDeclaration::RelocInitializer(
- Context->getGlobalDeclarationByID(Index), Offset));
+ CurGlobalVar->addInitializer(
+ Ice::VariableDeclaration::RelocInitializer::create(
+ Context->getGlobalDeclarationByID(Index), Offset));
return;
}
default:
@@ -2945,7 +2948,8 @@
}
bool IsProto = Values[2] == 1;
Ice::FunctionDeclaration *Func = Ice::FunctionDeclaration::create(
- Signature, CallingConv, Linkage, IsProto);
+ Context->getTranslator().getContext(), Signature, CallingConv, Linkage,
+ IsProto);
Context->setNextFunctionID(Func);
return;
}