Remove 'externGlobals' member from Module; instead find them when needed via new SymbolTable::GetMatchingVariables method.

This commit is contained in:
Matt Pharr
2011-10-04 06:36:31 -07:00
parent fa5050d5c7
commit a6fc657b40
8 changed files with 44 additions and 29 deletions

View File

@@ -377,8 +377,8 @@ lAddBitcode(const unsigned char *bitcode, int length,
static void static void
lDefineConstantInt(const char *name, int val, llvm::Module *module, lDefineConstantInt(const char *name, int val, llvm::Module *module,
SymbolTable *symbolTable) { SymbolTable *symbolTable) {
Symbol *pw = new Symbol(name, SourcePos(), AtomicType::UniformConstInt32); Symbol *pw = new Symbol(name, SourcePos(), AtomicType::UniformConstInt32,
pw->isStatic = true; SC_STATIC);
pw->constValue = new ConstExpr(pw->type, val, SourcePos()); pw->constValue = new ConstExpr(pw->type, val, SourcePos());
LLVM_TYPE_CONST llvm::Type *ltype = LLVMTypes::Int32Type; LLVM_TYPE_CONST llvm::Type *ltype = LLVMTypes::Int32Type;
llvm::Constant *linit = LLVMInt32(val); llvm::Constant *linit = LLVMInt32(val);
@@ -395,8 +395,7 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
SymbolTable *symbolTable) { SymbolTable *symbolTable) {
std::vector<const Type *> args; std::vector<const Type *> args;
FunctionType *ft = new FunctionType(AtomicType::UniformInt32, args, SourcePos()); FunctionType *ft = new FunctionType(AtomicType::UniformInt32, args, SourcePos());
Symbol *sym = new Symbol(name, SourcePos(), ft); Symbol *sym = new Symbol(name, SourcePos(), ft, SC_STATIC);
sym->isStatic = true;
llvm::Function *func = module->getFunction(name); llvm::Function *func = module->getFunction(name);
assert(func != NULL); // it should be declared already... assert(func != NULL); // it should be declared already...
@@ -413,8 +412,7 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
static void static void
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) { lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
Symbol *pidx = new Symbol("programIndex", SourcePos(), Symbol *pidx = new Symbol("programIndex", SourcePos(),
AtomicType::VaryingConstInt32); AtomicType::VaryingConstInt32, SC_STATIC);
pidx->isStatic = true;
int pi[ISPC_MAX_NVEC]; int pi[ISPC_MAX_NVEC];
for (int i = 0; i < g->target.vectorWidth; ++i) for (int i = 0; i < g->target.vectorWidth; ++i)

View File

@@ -170,7 +170,7 @@ FunctionEmitContext::FunctionEmitContext(const Type *rt, llvm::Function *functio
diFile, diFile,
funcStartPos.first_line, funcStartPos.first_line,
retType, retType,
funSym->isStatic, funSym->storageClass == SC_STATIC,
true, /* is definition */ true, /* is definition */
flags, flags,
g->opt.level > 0, g->opt.level > 0,

View File

@@ -101,9 +101,7 @@ Declarator::AddArrayDimension(int size) {
void void
Declarator::InitFromDeclSpecs(DeclSpecs *ds) { Declarator::InitFromDeclSpecs(DeclSpecs *ds) {
sym->type = GetType(ds); sym->type = GetType(ds);
sym->storageClass = ds->storageClass;
if (ds->storageClass == SC_STATIC)
sym->isStatic = true;
} }

View File

@@ -1497,7 +1497,7 @@ lStoreAssignResult(llvm::Value *rv, llvm::Value *lv, const Type *type,
assert(baseSym->varyingCFDepth <= ctx->VaryingCFDepth()); assert(baseSym->varyingCFDepth <= ctx->VaryingCFDepth());
if (!g->opt.disableMaskedStoreToStore && if (!g->opt.disableMaskedStoreToStore &&
baseSym->varyingCFDepth == ctx->VaryingCFDepth() && baseSym->varyingCFDepth == ctx->VaryingCFDepth() &&
baseSym->isStatic == false && baseSym->storageClass != SC_STATIC &&
dynamic_cast<const ReferenceType *>(baseSym->type) == NULL) { dynamic_cast<const ReferenceType *>(baseSym->type) == NULL) {
// If the variable is declared at the same varying control flow // If the variable is declared at the same varying control flow
// depth as where it's being assigned, then we don't need to do any // depth as where it's being assigned, then we don't need to do any

View File

@@ -505,7 +505,6 @@ Module::AddGlobal(DeclSpecs *ds, Declarator *decl) {
// make sure it's a compile-time constant! // make sure it's a compile-time constant!
llvm::Constant *llvmInitializer = NULL; llvm::Constant *llvmInitializer = NULL;
if (ds->storageClass == SC_EXTERN || ds->storageClass == SC_EXTERN_C) { if (ds->storageClass == SC_EXTERN || ds->storageClass == SC_EXTERN_C) {
externGlobals.push_back(decl->sym);
if (decl->initExpr != NULL) if (decl->initExpr != NULL)
Error(decl->pos, "Initializer can't be provided with \"extern\" " Error(decl->pos, "Initializer can't be provided with \"extern\" "
"global variable \"%s\".", decl->sym->name.c_str()); "global variable \"%s\".", decl->sym->name.c_str());
@@ -1268,6 +1267,12 @@ lIsExternC(const Symbol *sym) {
} }
static bool
lIsExternGlobal(const Symbol *sym) {
return sym->storageClass == SC_EXTERN || sym->storageClass == SC_EXTERN_C;
}
bool bool
Module::writeHeader(const char *fn) { Module::writeHeader(const char *fn) {
FILE *f = fopen(fn, "w"); FILE *f = fopen(fn, "w");
@@ -1336,6 +1341,8 @@ Module::writeHeader(const char *fn) {
&exportedEnumTypes, &exportedVectorTypes); &exportedEnumTypes, &exportedVectorTypes);
// And do the same for the 'extern' globals // And do the same for the 'extern' globals
std::vector<Symbol *> externGlobals;
symbolTable->GetMatchingVariables(lIsExternGlobal, &externGlobals);
for (unsigned int i = 0; i < externGlobals.size(); ++i) for (unsigned int i = 0; i < externGlobals.size(); ++i)
lGetExportedTypes(externGlobals[i]->type, &exportedStructTypes, lGetExportedTypes(externGlobals[i]->type, &exportedStructTypes,
&exportedEnumTypes, &exportedVectorTypes); &exportedEnumTypes, &exportedVectorTypes);

View File

@@ -99,15 +99,6 @@ public:
private: private:
const char *filename; const char *filename;
/** This member records the global variables that have been defined
with 'extern' linkage, so that it's easy to include their
declarations in generated header files.
@todo FIXME: it would be nice to eliminate this and then query the
symbol table or the llvm Module for them when/if we need them.
*/
std::vector<Symbol *> externGlobals;
bool writeHeader(const char *filename); bool writeHeader(const char *filename);
bool writeObjectFileOrAssembly(OutputType outputType, const char *filename); bool writeObjectFileOrAssembly(OutputType outputType, const char *filename);
void execPreprocessor(const char *infilename, llvm::raw_string_ostream* ostream) const; void execPreprocessor(const char *infilename, llvm::raw_string_ostream* ostream) const;

View File

@@ -43,13 +43,14 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Symbol // Symbol
Symbol::Symbol(const std::string &n, SourcePos p, const Type *t) Symbol::Symbol(const std::string &n, SourcePos p, const Type *t,
StorageClass sc)
: pos(p), name(n) { : pos(p), name(n) {
storagePtr = NULL; storagePtr = NULL;
function = NULL; function = NULL;
type = t; type = t;
constValue = NULL; constValue = NULL;
isStatic = false; storageClass = sc;
varyingCFDepth = 0; varyingCFDepth = 0;
} }

30
sym.h
View File

@@ -41,6 +41,7 @@
#define ISPC_SYM_H #define ISPC_SYM_H
#include "ispc.h" #include "ispc.h"
#include "decl.h"
#include <map> #include <map>
class StructType; class StructType;
@@ -63,7 +64,8 @@ class Symbol {
public: public:
/** The Symbol constructor takes the name of the symbol, its /** The Symbol constructor takes the name of the symbol, its
position in a source file, and its type (if known). */ position in a source file, and its type (if known). */
Symbol(const std::string &name, SourcePos pos, const Type *t = NULL); Symbol(const std::string &name, SourcePos pos, const Type *t = NULL,
StorageClass sc = SC_NONE);
/** This method should only be called for function symbols; for them, /** This method should only be called for function symbols; for them,
it returns a mangled version of the function name with the argument it returns a mangled version of the function name with the argument
@@ -93,8 +95,8 @@ public:
storagePtr member will be its constant value. (This storagePtr member will be its constant value. (This
messiness is due to needing an ispc ConstExpr for the early messiness is due to needing an ispc ConstExpr for the early
constant folding optimizations). */ constant folding optimizations). */
bool isStatic; /*!< Records whether this symbol had a static qualifier in StorageClass storageClass;/*!< Records the storage class (if any) provided with the
its declaration. */ symbol's declaration. */
int varyingCFDepth; /*!< This member records the number of levels of nested 'varying' int varyingCFDepth; /*!< This member records the number of levels of nested 'varying'
control flow within which the symbol was declared. Having control flow within which the symbol was declared. Having
this value available makes it possible to avoid performing this value available makes it possible to avoid performing
@@ -186,6 +188,14 @@ public:
void GetMatchingFunctions(Predicate pred, void GetMatchingFunctions(Predicate pred,
std::vector<Symbol *> *matches) const; std::vector<Symbol *> *matches) const;
/** Returns all of the variable symbols in the symbol table that match
the given predicate. The predicate is defined as in the
GetMatchingFunctions() method.
*/
template <typename Predicate>
void GetMatchingVariables(Predicate pred,
std::vector<Symbol *> *matches) const;
/** Adds the named type to the symbol table. This is used for both /** Adds the named type to the symbol table. This is used for both
struct definitions (where <tt>struct Foo</tt> causes type \c Foo to struct definitions (where <tt>struct Foo</tt> causes type \c Foo to
be added to the symbol table) as well as for <tt>typedef</tt>s. be added to the symbol table) as well as for <tt>typedef</tt>s.
@@ -251,8 +261,8 @@ private:
}; };
template <typename Predicate> template <typename Predicate> void
void SymbolTable::GetMatchingFunctions(Predicate pred, SymbolTable::GetMatchingFunctions(Predicate pred,
std::vector<Symbol *> *matches) const { std::vector<Symbol *> *matches) const {
// Iterate through all function symbols and apply the given predicate. // Iterate through all function symbols and apply the given predicate.
// If it returns true, add the Symbol * to the provided vector. // If it returns true, add the Symbol * to the provided vector.
@@ -266,4 +276,14 @@ void SymbolTable::GetMatchingFunctions(Predicate pred,
} }
} }
template <typename Predicate> void
SymbolTable::GetMatchingVariables(Predicate pred,
std::vector<Symbol *> *matches) const {
for (unsigned int i = 0; i < variables.size(); ++i)
for (unsigned int j = 0; j < variables[i]->size(); ++j)
if (pred((*variables[i])[j]))
matches->push_back((*variables[i])[j]);
}
#endif // ISPC_SYM_H #endif // ISPC_SYM_H