From f1fef65157bac9fcb37eac934ffd58d3e1e3e7cb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 13 Oct 2001 06:35:09 +0000 Subject: [PATCH] Support pointers to globals happily git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@754 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bytecode/Writer/SlotCalculator.cpp | 46 +++++++++++++++++++++----- lib/VMCore/SlotCalculator.cpp | 46 +++++++++++++++++++++----- 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp index 38980e5e63a..3211e728ff2 100644 --- a/lib/Bytecode/Writer/SlotCalculator.cpp +++ b/lib/Bytecode/Writer/SlotCalculator.cpp @@ -70,6 +70,14 @@ SlotCalculator::SlotCalculator(const Method *M, bool IgnoreNamed) { void SlotCalculator::processModule() { SC_DEBUG("begin processModule!\n"); + // Add all of the constants that the global variables might refer to first. + // + for (Module::const_giterator I = TheModule->gbegin(), E = TheModule->gend(); + I != E; ++I) { + if ((*I)->hasInitializer()) + insertValue((*I)->getInitializer()); + } + // Add all of the global variables to the value table... // for_each(TheModule->gbegin(), TheModule->gend(), @@ -184,10 +192,10 @@ void SlotCalculator::purgeMethod() { for (unsigned i = 0; i < NumModuleTypes; ++i) { unsigned ModuleSize = ModuleLevel[i]; // Size of plane before method came TypePlane &CurPlane = Table[i]; - SC_DEBUG("Processing Plane " << i << " of size " << CurPlane.size() <::iterator NI = NodeMap.find(CurPlane.back()); assert(NI != NodeMap.end() && "Node not in nodemap?"); NodeMap.erase(NI); // Erase from nodemap @@ -224,13 +232,14 @@ int SlotCalculator::getValSlot(const Value *D) const { int SlotCalculator::insertValue(const Value *D) { if (isa(D) || isa(D)) { - const User *U = (const User *)D; + const User *U = cast(D); // This makes sure that if a constant has uses (for example an array // of const ints), that they are inserted also. Same for global variable // initializers. // - for_each(U->op_begin(), U->op_end(), - bind_obj(this, &SlotCalculator::insertValue)); + for(User::op_const_iterator I = U->op_begin(), E = U->op_end(); I != E; ++I) + if (!isa(*I)) // Don't chain insert global values + insertValue(*I); } int SlotNo = getValSlot(D); // Check to see if it's already in! @@ -257,7 +266,19 @@ int SlotCalculator::insertVal(const Value *D, bool dontIgnore = false) { // If it's a type, make sure that all subtypes of the type are included... if (const Type *TheTy = dyn_cast(D)) { - SC_DEBUG(" Inserted type: " << TheTy->getDescription() << endl); + + // Insert the current type before any subtypes. This is important because + // recursive types elements are inserted in a bottom up order. Changing + // this here can break things. For example: + // + // global { \2 * } { { \2 }* null } + // + int ResultSlot; + if ((ResultSlot = getValSlot(TheTy)) == -1) { + ResultSlot = doInsertVal(TheTy); + SC_DEBUG(" Inserted type: " << TheTy->getDescription() << " slot=" << + ResultSlot << endl); + } // Loop over any contained types in the definition... in reverse depth first // order. This assures that all of the leafs of a type are output before @@ -271,9 +292,12 @@ int SlotCalculator::insertVal(const Value *D, bool dontIgnore = false) { const Type *SubTy = *I; if (getValSlot(SubTy) == -1) { SC_DEBUG(" Inserting subtype: " << SubTy->getDescription() << endl); - doInsertVal(SubTy); + int Slot = doInsertVal(SubTy); + SC_DEBUG(" Inserted subtype: " << SubTy->getDescription() << + " slot=" << Slot << endl); } } + return ResultSlot; } // Okay, everything is happy, actually insert the silly value now... @@ -306,11 +330,15 @@ int SlotCalculator::doInsertVal(const Value *D) { if (Table.size() <= Ty) // Make sure we have the type plane allocated... Table.resize(Ty+1, TypePlane()); - SC_DEBUG(" Inserting value [" << Ty << "] = " << D << endl); - // Insert node into table and NodeMap... unsigned DestSlot = NodeMap[D] = Table[Ty].size(); Table[Ty].push_back(D); + SC_DEBUG(" Inserting value [" << Ty << "] = " << D << " slot=" << + DestSlot << " ["); + // G = Global, C = ConstPoolVal, T = Type, M = Method, o = other + SC_DEBUG((isa(D) ? "G" : (isa(D) ? "C" : + (isa(D) ? "T" : (isa(D) ? "M" : "o"))))); + SC_DEBUG("]\n"); return (int)DestSlot; } diff --git a/lib/VMCore/SlotCalculator.cpp b/lib/VMCore/SlotCalculator.cpp index 38980e5e63a..3211e728ff2 100644 --- a/lib/VMCore/SlotCalculator.cpp +++ b/lib/VMCore/SlotCalculator.cpp @@ -70,6 +70,14 @@ SlotCalculator::SlotCalculator(const Method *M, bool IgnoreNamed) { void SlotCalculator::processModule() { SC_DEBUG("begin processModule!\n"); + // Add all of the constants that the global variables might refer to first. + // + for (Module::const_giterator I = TheModule->gbegin(), E = TheModule->gend(); + I != E; ++I) { + if ((*I)->hasInitializer()) + insertValue((*I)->getInitializer()); + } + // Add all of the global variables to the value table... // for_each(TheModule->gbegin(), TheModule->gend(), @@ -184,10 +192,10 @@ void SlotCalculator::purgeMethod() { for (unsigned i = 0; i < NumModuleTypes; ++i) { unsigned ModuleSize = ModuleLevel[i]; // Size of plane before method came TypePlane &CurPlane = Table[i]; - SC_DEBUG("Processing Plane " << i << " of size " << CurPlane.size() <::iterator NI = NodeMap.find(CurPlane.back()); assert(NI != NodeMap.end() && "Node not in nodemap?"); NodeMap.erase(NI); // Erase from nodemap @@ -224,13 +232,14 @@ int SlotCalculator::getValSlot(const Value *D) const { int SlotCalculator::insertValue(const Value *D) { if (isa(D) || isa(D)) { - const User *U = (const User *)D; + const User *U = cast(D); // This makes sure that if a constant has uses (for example an array // of const ints), that they are inserted also. Same for global variable // initializers. // - for_each(U->op_begin(), U->op_end(), - bind_obj(this, &SlotCalculator::insertValue)); + for(User::op_const_iterator I = U->op_begin(), E = U->op_end(); I != E; ++I) + if (!isa(*I)) // Don't chain insert global values + insertValue(*I); } int SlotNo = getValSlot(D); // Check to see if it's already in! @@ -257,7 +266,19 @@ int SlotCalculator::insertVal(const Value *D, bool dontIgnore = false) { // If it's a type, make sure that all subtypes of the type are included... if (const Type *TheTy = dyn_cast(D)) { - SC_DEBUG(" Inserted type: " << TheTy->getDescription() << endl); + + // Insert the current type before any subtypes. This is important because + // recursive types elements are inserted in a bottom up order. Changing + // this here can break things. For example: + // + // global { \2 * } { { \2 }* null } + // + int ResultSlot; + if ((ResultSlot = getValSlot(TheTy)) == -1) { + ResultSlot = doInsertVal(TheTy); + SC_DEBUG(" Inserted type: " << TheTy->getDescription() << " slot=" << + ResultSlot << endl); + } // Loop over any contained types in the definition... in reverse depth first // order. This assures that all of the leafs of a type are output before @@ -271,9 +292,12 @@ int SlotCalculator::insertVal(const Value *D, bool dontIgnore = false) { const Type *SubTy = *I; if (getValSlot(SubTy) == -1) { SC_DEBUG(" Inserting subtype: " << SubTy->getDescription() << endl); - doInsertVal(SubTy); + int Slot = doInsertVal(SubTy); + SC_DEBUG(" Inserted subtype: " << SubTy->getDescription() << + " slot=" << Slot << endl); } } + return ResultSlot; } // Okay, everything is happy, actually insert the silly value now... @@ -306,11 +330,15 @@ int SlotCalculator::doInsertVal(const Value *D) { if (Table.size() <= Ty) // Make sure we have the type plane allocated... Table.resize(Ty+1, TypePlane()); - SC_DEBUG(" Inserting value [" << Ty << "] = " << D << endl); - // Insert node into table and NodeMap... unsigned DestSlot = NodeMap[D] = Table[Ty].size(); Table[Ty].push_back(D); + SC_DEBUG(" Inserting value [" << Ty << "] = " << D << " slot=" << + DestSlot << " ["); + // G = Global, C = ConstPoolVal, T = Type, M = Method, o = other + SC_DEBUG((isa(D) ? "G" : (isa(D) ? "C" : + (isa(D) ? "T" : (isa(D) ? "M" : "o"))))); + SC_DEBUG("]\n"); return (int)DestSlot; }