//===----------------------------------------------------------------------===//
#include "ValueEnumerator.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/ValueSymbolTable.h"
-#include "llvm/Instructions.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
-static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) {
- return V.first->getType()->isIntegerTy();
+static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
+ return V.first->getType()->isIntOrIntVectorTy();
}
/// ValueEnumerator - Enumerate module-level information.
I != E; ++I)
EnumerateValue(I->getAliasee());
- // Insert constants and metadata that are named at module level into the slot
+ // Insert constants and metadata that are named at module level into the slot
// pool so that the module symbol table can refer to them...
EnumerateValueSymbolTable(M->getValueSymbolTable());
EnumerateNamedMetadata(M);
I->getAllMetadataOtherThanDebugLoc(MDs);
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
-
+
if (!I->getDebugLoc().isUnknown()) {
MDNode *Scope, *IA;
I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext());
OptimizeConstants(FirstConstant, Values.size());
}
-
unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
InstructionMapType::const_iterator I = InstructionMap.find(Inst);
assert(I != InstructionMap.end() && "Instruction is not mapped!");
return I->second-1;
}
+void ValueEnumerator::dump() const {
+ print(dbgs(), ValueMap, "Default");
+ dbgs() << '\n';
+ print(dbgs(), MDValueMap, "MetaData");
+ dbgs() << '\n';
+}
+
+void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
+ const char *Name) const {
+
+ OS << "Map Name: " << Name << "\n";
+ OS << "Size: " << Map.size() << "\n";
+ for (ValueMapType::const_iterator I = Map.begin(),
+ E = Map.end(); I != E; ++I) {
+
+ const Value *V = I->first;
+ if (V->hasName())
+ OS << "Value: " << V->getName();
+ else
+ OS << "Value: [null]\n";
+ V->dump();
+
+ OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
+ for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
+ UI != UE; ++UI) {
+ if (UI != V->use_begin())
+ OS << ",";
+ if((*UI)->hasName())
+ OS << " " << (*UI)->getName();
+ else
+ OS << " [null]";
+
+ }
+ OS << "\n\n";
+ }
+}
+
// Optimize constant ordering.
namespace {
struct CstSortPredicate {
CstSortPredicate P(*this);
std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P);
- // Ensure that integer constants are at the start of the constant pool. This
- // is important so that GEP structure indices come before gep constant exprs.
+ // Ensure that integer and vector of integer constants are at the start of the
+ // constant pool. This is important so that GEP structure indices come before
+ // gep constant exprs.
std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,
- isIntegerValue);
+ isIntOrIntVectorValue);
// Rebuild the modified portion of ValueMap.
for (; CstStart != CstEnd; ++CstStart)
if (const Constant *C = dyn_cast<Constant>(V)) {
if (isa<GlobalValue>(C)) {
// Initializers for globals are handled explicitly elsewhere.
- } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
- // Do not enumerate the initializers for an array of simple characters.
- // The initializers just pollute the value table, and we emit the strings
- // specially.
} else if (C->getNumOperands()) {
// If a constant has operands, enumerate them. This makes sure that if a
// constant has uses (for example an array of const ints), that they are
}
-void ValueEnumerator::EnumerateType(const Type *Ty) {
+void ValueEnumerator::EnumerateType(Type *Ty) {
unsigned *TypeID = &TypeMap[Ty];
// We've already seen this type.
// If it is a non-anonymous struct, mark the type as being visited so that we
// don't recursively visit it. This is safe because we allow forward
// references of these in the bitcode reader.
- if (const StructType *STy = dyn_cast<StructType>(Ty))
- if (!STy->isAnonymous())
+ if (StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isLiteral())
*TypeID = ~0U;
-
+
// Enumerate all of the subtypes before we enumerate this type. This ensures
// that the type will be enumerated in an order that can be directly built.
for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
I != E; ++I)
EnumerateType(*I);
-
+
// Refresh the TypeID pointer in case the table rehashed.
TypeID = &TypeMap[Ty];
-
+
// Check to see if we got the pointer another way. This can happen when
// enumerating recursive types that hit the base case deeper than they start.
//
// then emit the definition now that all of its contents are available.
if (*TypeID && *TypeID != ~0U)
return;
-
+
// Add this type now that its contents are all happily enumerated.
Types.push_back(Ty);
-
+
*TypeID = Types.size();
}
// walk through it, enumerating the types of the constant.
void ValueEnumerator::EnumerateOperandType(const Value *V) {
EnumerateType(V->getType());
-
+
if (const Constant *C = dyn_cast<Constant>(V)) {
// If this constant is already enumerated, ignore it, we know its type must
// be enumerated.
// them.
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
const Value *Op = C->getOperand(i);
-
+
// Don't enumerate basic blocks here, this happens as operands to
// blockaddress.
if (isa<BasicBlock>(Op)) continue;
-
+
EnumerateOperandType(Op);
}
EnumerateMetadata(V);
}
-void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) {
+void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
if (PAL.isEmpty()) return; // null is always 0.
+
// Do a lookup.
- unsigned &Entry = AttributeMap[PAL.getRawPointer()];
+ unsigned &Entry = AttributeMap[PAL];
if (Entry == 0) {
// Never saw this before, add it.
- Attributes.push_back(PAL);
- Entry = Attributes.size();
+ Attribute.push_back(PAL);
+ Entry = Attribute.size();
+ }
+
+ // Do lookups for all attribute groups.
+ for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
+ AttributeSet AS = PAL.getSlotAttributes(i);
+ unsigned &Entry = AttributeGroupMap[AS];
+ if (Entry == 0) {
+ AttributeGroups.push_back(AS);
+ Entry = AttributeGroups.size();
+ }
}
}
if (N->isFunctionLocal() && N->getFunction())
FnLocalMDVector.push_back(N);
}
-
+
if (!I->getType()->isVoidTy())
EnumerateValue(I);
}