[llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y
Chris Lattner
lattner at cs.uiuc.edu
Wed Jul 14 16:03:57 PDT 2004
Changes in directory llvm/lib/AsmParser:
llvmAsmParser.y updated: 1.187 -> 1.188
---
Log message:
** Finally DeclareNewGlobalValue is dead!
* Simplify a lot of code because type's cannot be in function symbol tables
* Fix memory leaks in handling of redefined function prototypes
* Don't use SymbolTable directly for stuff that we can go through the Module
for.
* Fix some minor bugs on obscure testcases like:
test/Feature/globalredefinition.ll
* Do not create GlobalVariable objects for forward referenced Functions!
* When forward referencing a function in a constant expression, do not create
a placeholder, add a bunch of references to it, then turn around and
replaceAllUsesOfWith on it with a new global, deleting the placeholder.
Instead, when we find the real definition of the global, just use the
placeholder instead of creating a new object.
This substantially simplifies the asmwriter and should even speed it up on
cases heavy in constantexprs (like C++, Java, MSIL)...
---
Diffs of the changes: (+89 -124)
Index: llvm/lib/AsmParser/llvmAsmParser.y
diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.187 llvm/lib/AsmParser/llvmAsmParser.y:1.188
--- llvm/lib/AsmParser/llvmAsmParser.y:1.187 Wed Jul 14 16:44:00 2004
+++ llvm/lib/AsmParser/llvmAsmParser.y Wed Jul 14 18:03:46 2004
@@ -126,35 +126,6 @@
}
return Ret;
}
-
- // DeclareNewGlobalValue - Called every time a new GV has been defined. This
- // is used to remove things from the forward declaration map, resolving them
- // to the correct thing as needed.
- //
- void DeclareNewGlobalValue(GlobalValue *GV, ValID D) {
- // Check to see if there is a forward reference to this global variable...
- // if there is, eliminate it and patch the reference to use the new def'n.
- GlobalRefsType::iterator I =
- GlobalRefs.find(std::make_pair(GV->getType(), D));
-
- if (I != GlobalRefs.end()) {
- GlobalValue *OldGV = I->second; // Get the placeholder...
- I->first.second.destroy(); // Free string memory if necessary
-
- // Replace all uses of the placeholder with the new GV
- OldGV->replaceAllUsesWith(GV);
-
- // Remove OldGV from the module...
- if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(OldGV))
- CurrentModule->getGlobalList().erase(GVar);
- else
- CurrentModule->getFunctionList().erase(cast<Function>(OldGV));
-
- // Remove the map entry for the global now that it has been created...
- GlobalRefs.erase(I);
- }
- }
-
} CurModule;
static struct PerFunctionInfo {
@@ -209,7 +180,6 @@
}
}
}
- CurModule.DeclareNewGlobalValue(CurrentFunction, FID);
Values.clear(); // Clear out function local definitions
Types.clear(); // Clear out function local types
@@ -237,41 +207,17 @@
static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
switch (D.Type) {
- case ValID::NumberVal: { // Is it a numbered definition?
- unsigned Num = (unsigned)D.Num;
-
+ case ValID::NumberVal: // Is it a numbered definition?
// Module constants occupy the lowest numbered slots...
- if (Num < CurModule.Types.size())
- return CurModule.Types[Num];
-
- Num -= CurModule.Types.size();
-
- // Check that the number is within bounds...
- if (Num <= CurFun.Types.size())
- return CurFun.Types[Num];
+ if ((unsigned)D.Num < CurModule.Types.size())
+ return CurModule.Types[(unsigned)D.Num];
break;
- }
- case ValID::NameVal: { // Is it a named definition?
- std::string Name(D.Name);
- SymbolTable *SymTab = 0;
- Type *N = 0;
- if (inFunctionScope()) {
- SymTab = &CurFun.CurrentFunction->getSymbolTable();
- N = SymTab->lookupType(Name);
+ case ValID::NameVal: // Is it a named definition?
+ if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) {
+ D.destroy(); // Free old strdup'd memory...
+ return N;
}
-
- if (N == 0) {
- // Symbol table doesn't automatically chain yet... because the function
- // hasn't been added to the module...
- //
- SymTab = &CurModule.CurrentModule->getSymbolTable();
- N = SymTab->lookupType(Name);
- if (N == 0) break;
- }
-
- D.destroy(); // Free old strdup'd memory...
- return cast<Type>(N);
- }
+ break;
default:
ThrowException("Internal parser error: Invalid symbol type reference!");
}
@@ -438,7 +384,8 @@
break;
case ValID::NameVal: // Is it a named definition?
Name = ID.Name;
- if (Value *N = lookupInSymbolTable(Type::LabelTy, Name))
+ if (Value *N = CurFun.CurrentFunction->
+ getSymbolTable().lookup(Type::LabelTy, Name))
BB = cast<BasicBlock>(N);
break;
}
@@ -605,20 +552,43 @@
if (isa<FunctionType>(Ty))
ThrowException("Cannot declare global vars of function type!");
- // If this global has a name, check to see if there is already a definition
- // of this global in the module. If so, merge as appropriate. Note that
- // this is really just a hack around problems in the CFE. :(
+ const PointerType *PTy = PointerType::get(Ty);
+
std::string Name;
if (NameStr) {
Name = NameStr; // Copy string
free(NameStr); // Free old string
+ }
- SymbolTable &ST = CurModule.CurrentModule->getSymbolTable();
- if (Value *Existing = ST.lookup(Ty, Name)) {
- // We are a simple redefinition of a value, check to see if it is defined
- // the same as the old one...
- GlobalVariable *EGV = cast<GlobalVariable>(Existing);
+ // See if this global value was forward referenced. If so, recycle the
+ // object.
+ ValID ID;
+ if (!Name.empty()) {
+ ID = ValID::create((char*)Name.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PTy].size());
+ }
+
+ if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
+ // Move the global to the end of the list, from whereever it was
+ // previously inserted.
+ GlobalVariable *GV = cast<GlobalVariable>(FWGV);
+ CurModule.CurrentModule->getGlobalList().remove(GV);
+ CurModule.CurrentModule->getGlobalList().push_back(GV);
+ GV->setInitializer(Initializer);
+ GV->setLinkage(Linkage);
+ GV->setConstant(isConstantGlobal);
+ return;
+ }
+ // If this global has a name, check to see if there is already a definition
+ // of this global in the module. If so, merge as appropriate. Note that
+ // this is really just a hack around problems in the CFE. :(
+ if (!Name.empty()) {
+ // We are a simple redefinition of a value, check to see if it is defined
+ // the same as the old one.
+ if (GlobalVariable *EGV =
+ CurModule.CurrentModule->getGlobalVariable(Name, Ty)) {
// We are allowed to redefine a global variable in two circumstances:
// 1. If at least one of the globals is uninitialized or
// 2. If both initializers have the same value.
@@ -636,36 +606,14 @@
return;
}
- ThrowException("Redefinition of value named '" + Name + "' in the '" +
- Ty->getDescription() + "' type plane!");
+ ThrowException("Redefinition of global variable named '" + Name +
+ "' in the '" + Ty->getDescription() + "' type plane!");
}
}
- const PointerType *PTy = PointerType::get(Ty);
-
- // See if this global value was forward referenced. If so, recycle the
- // object.
- ValID ID;
- if (!Name.empty()) {
- ID = ValID::create((char*)Name.c_str());
- } else {
- ID = ValID::create((int)CurModule.Values[PTy].size());
- }
-
- if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
- // Move the global to the end of the list, from whereever it was
- // previously inserted.
- GlobalVariable *GV = cast<GlobalVariable>(FWGV);
- CurModule.CurrentModule->getGlobalList().remove(GV);
- CurModule.CurrentModule->getGlobalList().push_back(GV);
- GV->setInitializer(Initializer);
- GV->setLinkage(Linkage);
- GV->setConstant(isConstantGlobal);
- } else {
- // Otherwise there is no existing GV to use, create one now.
- new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
- CurModule.CurrentModule);
- }
+ // Otherwise there is no existing GV to use, create one now.
+ new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
+ CurModule.CurrentModule);
}
// setTypeName - Set the specified type to the name given. The name may be
@@ -676,6 +624,7 @@
// allowed to be redefined in the specified context. If the name is a new name
// for the type plane, it is inserted and false is returned.
static bool setTypeName(const Type *T, char *NameStr) {
+ assert(!inFunctionScope() && "Can't give types function-local names!");
if (NameStr == 0) return false;
std::string Name(NameStr); // Copy string
@@ -685,12 +634,13 @@
if (T == Type::VoidTy)
ThrowException("Can't assign name '" + Name + "' to the void type!");
- SymbolTable &ST = inFunctionScope() ?
- CurFun.CurrentFunction->getSymbolTable() :
- CurModule.CurrentModule->getSymbolTable();
+ // Set the type name, checking for conflicts as we do so.
+ bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, T);
+
+ if (AlreadyExists) { // Inserting a name that is already defined???
+ const Type *Existing = CurModule.CurrentModule->getTypeByName(Name);
+ assert(Existing && "Conflict but no matching type?");
- // Inserting a name that is already defined???
- if (Type *Existing = ST.lookupType(Name)) {
// There is only one case where this is allowed: when we are refining an
// opaque type. In this case, Existing will be an opaque type.
if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) {
@@ -710,9 +660,6 @@
T->getDescription() + "' type plane!");
}
- // Okay, its a newly named type. Set its name.
- if (!Name.empty()) ST.insert(Name, T);
-
return false;
}
@@ -1292,16 +1239,19 @@
$2.destroy();
} else {
std::string Name;
+ if ($2.Type == ValID::NameVal) Name = $2.Name;
- /// FIXME: We shouldn't be creating global vars as forward refs for
- /// functions at all here!
- if (!isa<FunctionType>(PT->getElementType()))
- if ($2.Type == ValID::NameVal) Name = $2.Name;
-
- // Create a placeholder for the global variable reference...
- GlobalVariable *GV = new GlobalVariable(PT->getElementType(), false,
- GlobalValue::ExternalLinkage,0,
- Name, CurModule.CurrentModule);
+ // Create the forward referenced global.
+ GlobalValue *GV;
+ if (const FunctionType *FTy =
+ dyn_cast<FunctionType>(PT->getElementType())) {
+ GV = new Function(FTy, GlobalValue::ExternalLinkage, Name,
+ CurModule.CurrentModule);
+ } else {
+ GV = new GlobalVariable(PT->getElementType(), false,
+ GlobalValue::ExternalLinkage, 0,
+ Name, CurModule.CurrentModule);
+ }
// Keep track of the fact that we have a forward ref to recycle it
CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV));
@@ -1551,6 +1501,7 @@
FunctionHeaderH : TypesV Name '(' ArgList ')' {
UnEscapeLexed($2);
std::string FunctionName($2);
+ free($2); // Free strdup'd memory!
if (!(*$1)->isFirstClassType() && *$1 != Type::VoidTy)
ThrowException("LLVM functions cannot return aggregate types!");
@@ -1569,25 +1520,39 @@
const PointerType *PFT = PointerType::get(FT);
delete $1;
+ ValID ID;
+ if (!FunctionName.empty()) {
+ ID = ValID::create((char*)FunctionName.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PFT].size());
+ }
+
Function *Fn = 0;
- // Is the function already in symtab?
- if ((Fn = CurModule.CurrentModule->getFunction(FunctionName, FT))) {
- // Yes it is. If this is the case, either we need to be a forward decl,
- // or it needs to be.
+ // See if this function was forward referenced. If so, recycle the object.
+ if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
+ // Move the function to the end of the list, from whereever it was
+ // previously inserted.
+ Fn = cast<Function>(FWRef);
+ CurModule.CurrentModule->getFunctionList().remove(Fn);
+ CurModule.CurrentModule->getFunctionList().push_back(Fn);
+ } else if (!FunctionName.empty() && // Merge with an earlier prototype?
+ (Fn = CurModule.CurrentModule->getFunction(FunctionName, FT))) {
+ // If this is the case, either we need to be a forward decl, or it needs
+ // to be.
if (!CurFun.isDeclare && !Fn->isExternal())
ThrowException("Redefinition of function '" + FunctionName + "'!");
- // Make sure to strip off any argument names so we can't get conflicts...
- for (Function::aiterator AI = Fn->abegin(), AE = Fn->aend(); AI != AE; ++AI)
- AI->setName("");
+ // Make sure to strip off any argument names so we can't get conflicts.
+ if (Fn->isExternal())
+ for (Function::aiterator AI = Fn->abegin(), AE = Fn->aend();
+ AI != AE; ++AI)
+ AI->setName("");
} else { // Not already defined?
Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName,
CurModule.CurrentModule);
InsertValue(Fn, CurModule.Values);
- CurModule.DeclareNewGlobalValue(Fn, ValID::create($2));
}
- free($2); // Free strdup'd memory!
CurFun.FunctionStart(Fn);
More information about the llvm-commits
mailing list