Remove dynamic allocation/indirection from GCOVBlocks owned by GCOVFunction

Since these are all created in the DenseMap before they are referenced,
there's no problem with pointer validity by the time it's required. This
removes another use of DeleteContainerSeconds/manual memory management
which I'm cleaning up from time to time.

llvm-svn: 224744
This commit is contained in:
David Blaikie 2014-12-22 23:12:42 +00:00
parent d9e64b6c08
commit ea37c1173e
1 changed files with 25 additions and 22 deletions

View File

@ -285,6 +285,14 @@ namespace {
DeleteContainerSeconds(LinesByFile);
}
GCOVBlock(const GCOVBlock &RHS) : GCOVRecord(RHS), Number(RHS.Number) {
// Only allow copy before edges and lines have been added. After that,
// there are inter-block pointers (eg: edges) that won't take kindly to
// blocks being copied or moved around.
assert(LinesByFile.empty());
assert(OutEdges.empty());
}
private:
friend class GCOVFunction;
@ -304,20 +312,20 @@ namespace {
class GCOVFunction : public GCOVRecord {
public:
GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident,
bool UseCfgChecksum) :
SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0) {
bool UseCfgChecksum)
: SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0),
ReturnBlock(1, os) {
this->os = os;
Function *F = SP.getFunction();
DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
Function::iterator BB = F->begin(), E = F->end();
Blocks[BB++] = new GCOVBlock(0, os);
ReturnBlock = new GCOVBlock(1, os);
uint32_t i = 2;
for (; BB != E; ++BB) {
Blocks[BB] = new GCOVBlock(i++, os);
uint32_t i = 0;
for (auto &BB : *F) {
// Skip index 1 (0, 2, 3, 4, ...) because that's assigned to the
// ReturnBlock.
bool first = i == 0;
Blocks.insert(std::make_pair(&BB, GCOVBlock(i++ + !first, os)));
}
std::string FunctionNameAndLine;
@ -327,17 +335,12 @@ namespace {
FuncChecksum = hash_value(FunctionNameAndLine);
}
~GCOVFunction() {
DeleteContainerSeconds(Blocks);
delete ReturnBlock;
}
GCOVBlock &getBlock(BasicBlock *BB) {
return *Blocks[BB];
return Blocks.find(BB)->second;
}
GCOVBlock &getReturnBlock() {
return *ReturnBlock;
return ReturnBlock;
}
std::string getEdgeDestinations() {
@ -345,7 +348,7 @@ namespace {
raw_string_ostream EDOS(EdgeDestinations);
Function *F = Blocks.begin()->first->getParent();
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
GCOVBlock &Block = *Blocks[I];
GCOVBlock &Block = getBlock(I);
for (int i = 0, e = Block.OutEdges.size(); i != e; ++i)
EDOS << Block.OutEdges[i]->Number;
}
@ -387,7 +390,7 @@ namespace {
if (Blocks.empty()) return;
Function *F = Blocks.begin()->first->getParent();
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
GCOVBlock &Block = *Blocks[I];
GCOVBlock &Block = getBlock(I);
if (Block.OutEdges.empty()) continue;
writeBytes(EdgeTag, 4);
@ -403,7 +406,7 @@ namespace {
// Emit lines for each block.
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
Blocks[I]->writeOut();
getBlock(I).writeOut();
}
}
@ -413,8 +416,8 @@ namespace {
uint32_t FuncChecksum;
bool UseCfgChecksum;
uint32_t CfgChecksum;
DenseMap<BasicBlock *, GCOVBlock *> Blocks;
GCOVBlock *ReturnBlock;
DenseMap<BasicBlock *, GCOVBlock> Blocks;
GCOVBlock ReturnBlock;
};
}