diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 | 
| commit | 59850d0874429601812bc13408cb1f776649027c (patch) | |
| tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/Bitcode/Writer/ValueEnumerator.cpp | |
| parent | 18f153bdb9db52e7089a2d5293b96c45a3124a26 (diff) | |
Notes
Diffstat (limited to 'lib/Bitcode/Writer/ValueEnumerator.cpp')
| -rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 167 | 
1 files changed, 117 insertions, 50 deletions
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 32b2819762db5..60253ad91e6ec 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -14,7 +14,7 @@  #include "ValueEnumerator.h"  #include "llvm/Constants.h"  #include "llvm/DerivedTypes.h" -#include "llvm/MDNode.h" +#include "llvm/Metadata.h"  #include "llvm/Module.h"  #include "llvm/TypeSymbolTable.h"  #include "llvm/ValueSymbolTable.h" @@ -40,6 +40,8 @@ static bool CompareByFrequency(const std::pair<const llvm::Type*,  /// ValueEnumerator - Enumerate module-level information.  ValueEnumerator::ValueEnumerator(const Module *M) { +  InstructionCount = 0; +    // Enumerate the global variables.    for (Module::const_global_iterator I = M->global_begin(),           E = M->global_end(); I != E; ++I) @@ -55,10 +57,10 @@ ValueEnumerator::ValueEnumerator(const Module *M) {    for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();         I != E; ++I)      EnumerateValue(I); -   +    // Remember what is the cutoff between globalvalue's and other constants.    unsigned FirstConstant = Values.size(); -   +    // Enumerate the global variable initializers.    for (Module::const_global_iterator I = M->global_begin(),           E = M->global_end(); I != E; ++I) @@ -69,24 +71,25 @@ ValueEnumerator::ValueEnumerator(const Module *M) {    for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();         I != E; ++I)      EnumerateValue(I->getAliasee()); -   +    // Enumerate types used by the type symbol table.    EnumerateTypeSymbolTable(M->getTypeSymbolTable());    // Insert constants that are named at module level into the slot pool so that    // the module symbol table can refer to them...    EnumerateValueSymbolTable(M->getValueSymbolTable()); -   +    // Enumerate types used by function bodies and argument lists.    for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { -     +      for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();           I != E; ++I)        EnumerateType(I->getType()); -     + +    MetadataContext &TheMetadata = F->getContext().getMetadata();      for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)        for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){ -        for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();  +        for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();               OI != E; ++OI)            EnumerateOperandType(*OI);          EnumerateType(I->getType()); @@ -94,16 +97,24 @@ ValueEnumerator::ValueEnumerator(const Module *M) {            EnumerateAttributes(CI->getAttributes());          else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))            EnumerateAttributes(II->getAttributes()); + +        // Enumerate metadata attached with this instruction. +        const MetadataContext::MDMapTy *MDs = TheMetadata.getMDs(I); +        if (MDs) +          for (MetadataContext::MDMapTy::const_iterator MI = MDs->begin(), +                 ME = MDs->end(); MI != ME; ++MI) +            if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second)) +              EnumerateMetadata(MDN);        }    } -   +    // Optimize constant ordering.    OptimizeConstants(FirstConstant, Values.size()); -     +    // Sort the type table by frequency so that most commonly used types are early    // in the table (have low bit-width).    std::stable_sort(Types.begin(), Types.end(), CompareByFrequency); -     +    // Partition the Type ID's so that the single-value types occur before the    // aggregate types.  This allows the aggregate types to be dropped from the    // type table after parsing the global variable initializers. @@ -114,6 +125,28 @@ ValueEnumerator::ValueEnumerator(const Module *M) {      TypeMap[Types[i].first] = i+1;  } +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; +} + +void ValueEnumerator::setInstructionID(const Instruction *I) { +  InstructionMap[I] = InstructionCount++; +} + +unsigned ValueEnumerator::getValueID(const Value *V) const { +  if (isa<MetadataBase>(V)) { +    ValueMapType::const_iterator I = MDValueMap.find(V); +    assert(I != MDValueMap.end() && "Value not in slotcalculator!"); +    return I->second-1; +  } + +  ValueMapType::const_iterator I = ValueMap.find(V); +  assert(I != ValueMap.end() && "Value not in slotcalculator!"); +  return I->second-1; +} +  // Optimize constant ordering.  namespace {    struct CstSortPredicate { @@ -123,7 +156,7 @@ namespace {                      const std::pair<const Value*, unsigned> &RHS) {        // Sort by plane.        if (LHS.first->getType() != RHS.first->getType()) -        return VE.getTypeID(LHS.first->getType()) <  +        return VE.getTypeID(LHS.first->getType()) <                 VE.getTypeID(RHS.first->getType());        // Then by frequency.        return LHS.second > RHS.second; @@ -134,15 +167,15 @@ namespace {  /// OptimizeConstants - Reorder constant pool for denser encoding.  void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {    if (CstStart == CstEnd || CstStart+1 == CstEnd) return; -   +    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.    std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,                   isIntegerValue); -   +    // Rebuild the modified portion of ValueMap.    for (; CstStart != CstEnd; ++CstStart)      ValueMap[Values[CstStart].first] = CstStart+1; @@ -152,7 +185,7 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {  /// EnumerateTypeSymbolTable - Insert all of the types in the specified symbol  /// table.  void ValueEnumerator::EnumerateTypeSymbolTable(const TypeSymbolTable &TST) { -  for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();  +  for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();         TI != TE; ++TI)      EnumerateType(TI->second);  } @@ -160,14 +193,57 @@ void ValueEnumerator::EnumerateTypeSymbolTable(const TypeSymbolTable &TST) {  /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol  /// table into the values table.  void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) { -  for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();  +  for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();         VI != VE; ++VI)      EnumerateValue(VI->getValue());  } +void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) { +  // Check to see if it's already in! +  unsigned &MDValueID = MDValueMap[MD]; +  if (MDValueID) { +    // Increment use count. +    MDValues[MDValueID-1].second++; +    return; +  } + +  // Enumerate the type of this value. +  EnumerateType(MD->getType()); + +  if (const MDNode *N = dyn_cast<MDNode>(MD)) { +    MDValues.push_back(std::make_pair(MD, 1U)); +    MDValueMap[MD] = MDValues.size(); +    MDValueID = MDValues.size(); +    for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); +         I != E; ++I) { +      if (*I) +        EnumerateValue(*I); +      else +        EnumerateType(Type::getVoidTy(MD->getContext())); +    } +    return; +  } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(MD)) { +    for(NamedMDNode::const_elem_iterator I = N->elem_begin(), +          E = N->elem_end(); I != E; ++I) { +      MetadataBase *M = *I; +      EnumerateValue(M); +    } +    MDValues.push_back(std::make_pair(MD, 1U)); +    MDValueMap[MD] = Values.size(); +    return; +  } + +  // Add the value. +  MDValues.push_back(std::make_pair(MD, 1U)); +  MDValueID = MDValues.size(); +} +  void ValueEnumerator::EnumerateValue(const Value *V) { -  assert(V->getType() != Type::VoidTy && "Can't insert void values!"); -   +  assert(V->getType() != Type::getVoidTy(V->getContext()) && +         "Can't insert void values!"); +  if (const MetadataBase *MB = dyn_cast<MetadataBase>(V)) +    return EnumerateMetadata(MB); +    // Check to see if it's already in!    unsigned &ValueID = ValueMap[V];    if (ValueID) { @@ -178,7 +254,7 @@ void ValueEnumerator::EnumerateValue(const Value *V) {    // Enumerate the type of this value.    EnumerateType(V->getType()); -   +    if (const Constant *C = dyn_cast<Constant>(V)) {      if (isa<GlobalValue>(C)) {        // Initializers for globals are handled explicitly elsewhere. @@ -190,7 +266,7 @@ void ValueEnumerator::EnumerateValue(const Value *V) {        // 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        // inserted also. -       +        // We prefer to enumerate them with values before we enumerate the user        // itself.  This makes it more likely that we can avoid forward references        // in the reader.  We know that there can be no cycles in the constants @@ -198,27 +274,15 @@ void ValueEnumerator::EnumerateValue(const Value *V) {        for (User::const_op_iterator I = C->op_begin(), E = C->op_end();             I != E; ++I)          EnumerateValue(*I); -       +        // Finally, add the value.  Doing this could make the ValueID reference be        // dangling, don't reuse it.        Values.push_back(std::make_pair(V, 1U));        ValueMap[V] = Values.size();        return; -    } else if (const MDNode *N = dyn_cast<MDNode>(C)) { -      for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); -           I != E; ++I) { -        if (*I) -          EnumerateValue(*I); -        else -          EnumerateType(Type::VoidTy); -      } - -      Values.push_back(std::make_pair(V, 1U)); -      ValueMap[V] = Values.size(); -      return;      }    } -   +    // Add the value.    Values.push_back(std::make_pair(V, 1U));    ValueID = Values.size(); @@ -227,17 +291,17 @@ void ValueEnumerator::EnumerateValue(const Value *V) {  void ValueEnumerator::EnumerateType(const Type *Ty) {    unsigned &TypeID = TypeMap[Ty]; -   +    if (TypeID) {      // If we've already seen this type, just increase its occurrence count.      Types[TypeID-1].second++;      return;    } -   +    // First time we saw this type, add it.    Types.push_back(std::make_pair(Ty, 1U));    TypeID = Types.size(); -   +    // Enumerate subtypes.    for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();         I != E; ++I) @@ -259,10 +323,14 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {        EnumerateOperandType(C->getOperand(i));      if (const MDNode *N = dyn_cast<MDNode>(V)) { -      for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) -        EnumerateOperandType(N->getElement(i)); +      for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { +        Value *Elem = N->getElement(i); +        if (Elem) +          EnumerateOperandType(Elem); +      }      } -  } +  } else if (isa<MDString>(V) || isa<MDNode>(V)) +    EnumerateValue(V);  }  void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) { @@ -279,18 +347,18 @@ void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) {  void ValueEnumerator::incorporateFunction(const Function &F) {    NumModuleValues = Values.size(); -   +    // Adding function arguments to the value table.    for(Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();        I != E; ++I)      EnumerateValue(I);    FirstFuncConstantID = Values.size(); -   +    // Add all function-level constants to the value table.    for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) -      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();  +      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();             OI != E; ++OI) {          if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||              isa<InlineAsm>(*OI)) @@ -299,20 +367,20 @@ void ValueEnumerator::incorporateFunction(const Function &F) {      BasicBlocks.push_back(BB);      ValueMap[BB] = BasicBlocks.size();    } -   +    // Optimize the constant layout.    OptimizeConstants(FirstFuncConstantID, Values.size()); -   +    // Add the function's parameter attributes so they are available for use in    // the function's instruction.    EnumerateAttributes(F.getAttributes());    FirstInstID = Values.size(); -   +    // Add all of the instructions.    for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { -      if (I->getType() != Type::VoidTy) +      if (I->getType() != Type::getVoidTy(F.getContext()))          EnumerateValue(I);      }    } @@ -324,8 +392,7 @@ void ValueEnumerator::purgeFunction() {      ValueMap.erase(Values[i].first);    for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)      ValueMap.erase(BasicBlocks[i]); -     +    Values.resize(NumModuleValues);    BasicBlocks.clear();  } -  | 
