Bug fix in CFG::getBlockEdgeImpl(): Use a BumpPtrAllocator to allocate
std::pair<CFGBlock*, CFGBlock*> that have an 8-byte alignment for use with ProgramPoint. This fixes a bug reported by Argiris where using std::set<> on Windows would result in a 4-byte alignment, not an 8-byte alignment. Fixes: <rdar://problem/5892265> llvm-svn: 50364
This commit is contained in:
parent
f592efe3f5
commit
6065ef6b9b
|
@ -281,7 +281,7 @@ public:
|
|||
//===--------------------------------------------------------------------===//
|
||||
|
||||
CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
|
||||
BlkExprMap(NULL), BlkEdgeSet(NULL) {};
|
||||
BlkExprMap(NULL), BlkEdgeSet(NULL), Allocator(NULL) {};
|
||||
|
||||
~CFG();
|
||||
|
||||
|
@ -298,13 +298,16 @@ private:
|
|||
// block-level expressions and their "statement number" in the CFG.
|
||||
void* BlkExprMap;
|
||||
|
||||
/// BlkEdgeSet - An opaque pointer to prevent inclusion of <set>.
|
||||
/// BlkEdgeSet - An opaque pointer to prevent inclusion of FoldingSet.h.
|
||||
/// The set contains std::pair<CFGBlock*,CFGBlock*> objects that have
|
||||
/// stable references for use by the 'BlockEdge' class. This set is intended
|
||||
/// to be sparse, as it only contains edges whether both the source
|
||||
/// and destination block have multiple successors/predecessors.
|
||||
void* BlkEdgeSet;
|
||||
|
||||
/// Alloc - An internal allocator used for BlkEdgeSet.
|
||||
void* Allocator;
|
||||
|
||||
friend class BlockEdge;
|
||||
|
||||
/// getBlockEdgeImpl - Utility method used by the class BlockEdge. The CFG
|
||||
|
|
|
@ -21,11 +21,10 @@
|
|||
#include "llvm/Support/GraphWriter.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <set>
|
||||
#include <llvm/Support/Allocator.h>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace clang;
|
||||
|
||||
|
@ -115,14 +114,20 @@ public:
|
|||
|
||||
// FIXME: Add support for ObjC-specific control-flow structures.
|
||||
|
||||
CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* Terminator) {
|
||||
// NYS == Not Yet Supported
|
||||
CFGBlock* NYS() {
|
||||
badCFG = true;
|
||||
return Block;
|
||||
}
|
||||
|
||||
CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* Terminator) {
|
||||
badCFG = true;
|
||||
return Block;
|
||||
CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* S){ return NYS();}
|
||||
CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) { return NYS(); }
|
||||
CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) { return NYS(); }
|
||||
CFGBlock* VisitObjCAtFinallyStmt(ObjCAtFinallyStmt* S) { return NYS(); }
|
||||
CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) { return NYS(); }
|
||||
|
||||
CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S){
|
||||
return NYS();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1150,21 +1155,77 @@ unsigned CFG::getNumBlkExprs() {
|
|||
}
|
||||
}
|
||||
|
||||
typedef std::set<std::pair<CFGBlock*,CFGBlock*> > BlkEdgeSetTy;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Internal Block-Edge Set; used for modeling persistent <CFGBlock*,CFGBlock*>
|
||||
// pairs for use with ProgramPoint.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
typedef std::pair<CFGBlock*,CFGBlock*> BPairTy;
|
||||
|
||||
namespace llvm {
|
||||
template<> struct FoldingSetTrait<BPairTy*> {
|
||||
static void Profile(const BPairTy* X, FoldingSetNodeID& profile) {
|
||||
profile.AddPointer(X->first);
|
||||
profile.AddPointer(X->second);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
typedef llvm::FoldingSetNodeWrapper<BPairTy*> PersistPairTy;
|
||||
typedef llvm::FoldingSet<PersistPairTy> BlkEdgeSetTy;
|
||||
|
||||
const std::pair<CFGBlock*,CFGBlock*>*
|
||||
CFG::getBlockEdgeImpl(const CFGBlock* B1, const CFGBlock* B2) {
|
||||
|
||||
BlkEdgeSetTy*& p = reinterpret_cast<BlkEdgeSetTy*&>(BlkEdgeSet);
|
||||
if (!p) p = new BlkEdgeSetTy();
|
||||
llvm::BumpPtrAllocator*& Alloc =
|
||||
reinterpret_cast<llvm::BumpPtrAllocator*&>(Allocator);
|
||||
|
||||
return &*(p->insert(std::make_pair(const_cast<CFGBlock*>(B1),
|
||||
const_cast<CFGBlock*>(B2))).first);
|
||||
if (!Alloc)
|
||||
Alloc = new llvm::BumpPtrAllocator();
|
||||
|
||||
BlkEdgeSetTy*& p = reinterpret_cast<BlkEdgeSetTy*&>(BlkEdgeSet);
|
||||
|
||||
if (!p)
|
||||
p = new BlkEdgeSetTy();
|
||||
|
||||
// Profile the edges.
|
||||
llvm::FoldingSetNodeID profile;
|
||||
void* InsertPos;
|
||||
|
||||
profile.AddPointer(B1);
|
||||
profile.AddPointer(B2);
|
||||
|
||||
PersistPairTy* V = p->FindNodeOrInsertPos(profile, InsertPos);
|
||||
|
||||
if (!V) {
|
||||
assert (llvm::AlignOf<BPairTy>::Alignment_LessEqual_8Bytes);
|
||||
|
||||
// Allocate the pair, forcing an 8-byte alignment.
|
||||
BPairTy* pair = (BPairTy*) Alloc->Allocate(sizeof(*pair), 8);
|
||||
|
||||
new (pair) BPairTy(const_cast<CFGBlock*>(B1),
|
||||
const_cast<CFGBlock*>(B2));
|
||||
|
||||
// Allocate the meta data to store the pair in the FoldingSet.
|
||||
PersistPairTy* ppair = (PersistPairTy*) Alloc->Allocate<PersistPairTy>();
|
||||
new (ppair) PersistPairTy(pair);
|
||||
|
||||
p->InsertNode(ppair, InsertPos);
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
return V->getValue();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Cleanup: CFG dstor.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
CFG::~CFG() {
|
||||
delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
|
||||
delete reinterpret_cast<BlkEdgeSetTy*>(BlkEdgeSet);
|
||||
delete reinterpret_cast<llvm::BumpPtrAllocator*> (Allocator);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1542,9 +1603,6 @@ void CFG::viewCFG() const {
|
|||
GraphHelper = &H;
|
||||
llvm::ViewGraph(this,"CFG");
|
||||
GraphHelper = NULL;
|
||||
#else
|
||||
std::cerr << "CFG::viewCFG is only available in debug builds on "
|
||||
<< "systems with Graphviz or gv!\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue