#include #include #include #include "AST.h" #include "ArraySet.h" #include "CfHeader.h" #include "CfSource.h" #include "CtReference.h" #include "CtTitaniumArray.h" #include "CtType.h" #include "code-assign.h" #include "code-grid.h" #include "code-util.h" #include "compiler.h" #include "decls.h" #include "domain-decls.h" #include "lgMacro.h" #include "stl-queue.h" #include "utils.h" #include "code.h" extern bool bounds_checking; ArraySet arrayTypes; // For internal functions that access grids, e.g., _ti_PTR and _ti_global_READ. string arrayInternal(const string &fn, bool global) { return string("_ti_") + (global ? "global_" : "") + fn; } // For methods like domain, slice, etc. string arrayMethodPrefix(const TypeNode *t) { return (t->modifiers() & Common::Local) ? string("_ti_arraymethod_") : string("_ti_global_arraymethod_"); } ///////////////////////////////////////////////////////////////////////////// // The section that follows handles the instantiation of grids for different // element types and arities. ///////////////////////////////////////////////////////////////////////////// #if 0 // not current used by anything /* Return 1 for arrays of things, 2 for arrays of arrays of things, etc. */ static int depth(const TypeNode *t) { int d = 0; while (t->isTitaniumArrayType()) { d++; t = t->elementType(); } return d; } #endif static string quickconv(char *arr, int arity) { string s; for (int i = arity; i >= 1; i--) s += "PFAST_DIVIDE((_i" + int2string(i - 1) + "-" + arr + ".base[" + int2string(i - 1) + "])*" + arr + ".sideFactors[" + int2string(i - 1) + "]," + arr + ".stride[" + int2string(i - 1) + "])" + (i == 1 ? "" : "+"); return s; } static string& printForallPointMacro(int arity) { static map_int_to_string memo; string s; string& temp = memo[arity]; int i; if (temp != "") return temp; s += "fprintf(f, \"%d"; for (i = 1; i < arity; i++) s += ",%d"; s += "\", _i0"; for (i = 1; i < arity; i++) s += string(", _i") + int2string(i); return (memo[arity] = (s + ")")); } /* Slices an domain up into rectangles, sets e and f to point to the first element of each square in turn (e indexes the x array, and f indexes the y array), and runs the given code segment. Used to break an N-dimensional array copy into a scatter/gather of rects. */ /* Before this macro is called, lo[0..N-1],hi[0..N-1],stride[0..N-1], and sideFactors[0..N-1] must be defined and set to the extents of the intersecting domain, which is the domain to be sliced up. **/ static string& sliceRectMacro(int arity) { static map_int_to_string memo; string s; string& temp = memo[arity]; if (temp != "") return temp; if (arity <= 2) { s += "do {} while (0)"; } else { /* do {int _i0, _i1, ...; } */ s += "do {int "; for (int i = 0; i < arity; i++) { s += string("_i") + int2string(i); if ((i + 1) < arity) s += ","; } s += ";"; /* The two dimensions of the squares are the Nth and N-1th dimensions of the array. */ /* _i1 = lo[1]; _i2 = lo[2]; */ for (int i = arity-2; i < arity; i++) { const string digits(int2string(i)); s += string("_i") + digits + " = lo[" + digits + "]; "; } for (int i = 0; i < arity-2; i++) { string is = int2string(i); string var = string("_i") + is; /* for( _i0 = lo[0]; _i0 <=hi[0]; _i0 += stride[0]) { */ s += "for(" + var + "=lo[" + is + "];" + var + "<=hi[" + is + "];" + var + "+=stride[" + is + "]) { "; /* Set e and f to [_i0,_i2,_i3,...,lo[arity-2],lo[arity-1]]. e and f will be indices into the memory spaces described by the Ti arrays x and y. */ s += "INDEX(e,x.A," + quickconv("x", arity) + ");"; s += "INDEX(f,y.A," + quickconv("y", arity) + ");"; s += "body;"; } for (int i = 2; i < arity; i++) { s += "}"; } s += "} while(0)"; } return memo[arity] = s; } static string& setBaseMacro(int arity) { static map_int_to_string memo; string s; string& temp = memo[arity]; if (temp != "") return temp; s += "do {int "; for (int i = 0; i < arity; i++) { const string digits(int2string(i)); s += string("_i") + digits + "=lo[" + digits + "]"; if ((i + 1) < arity) s += ","; } s += ";"; s += "INDEX(e,x.A," + quickconv("x", arity) + ");"; s += "INDEX(f,y.A," + quickconv("y", arity) + ");"; s += "} while (0)\n"; return memo[arity] = s; } static string forallMacro_help(int arity, bool convert) { string s,is,var; int i; // ed is the delta to e per iteration is = int2string(arity - 1); s += "{jint const ed=PFAST_DIVIDE(stride[" + is + "]*x.sideFactors[" + is + "]," "x.stride[" + is + "]);"; for (i = 0; i < arity - 1; i++) { is = int2string(i); var = string("_i") + is; s += "{jint " + var + "=lo[" + is + "];"; s += "for(;" + var + "<=hi[" + is + "];" + var + "+=stride[" + is + "])" "{" /* "cout<<\"" + var + "=\"<<" + var + ";" */ ; } is = int2string(i); var = string("_i") + is; s += "{jint " + var + "=lo[" + is + "];"; if (convert) { s += "T *e;"; s += "INDEX_LOCAL(e,TO_LOCAL(x.A)," + quickconv("x", arity) + ");"; } else { s += "PTR_TO_T e;"; s += "INDEX(e,x.A," + quickconv("x", arity) + ");"; } s += "for(;" + var + "<=hi[" + is + "];" + var + "+=stride[" + is + "])" + "{" + /* "cout<<\"" + var + "=\"<<" + var + ";" */ (convert?"localbody; INDEX_LOCAL":" body; INDEX") + "(e,e,ed);}"; for (i = 0; i < 2 * arity; i++) s += '}'; return s; } static string& forallMacro(int arity, bool isglobal) { static stringmap memo; string s; string memoindex = int2string(arity) + (isglobal?"GLOBAL":"LOCAL"); string& temp = memo[memoindex]; if (temp != "") return temp; if (!isglobal) { s = string("do{") + forallMacro_help(arity,false) + " } while(0)"; } else { s = "do { if (isDirectlyAddressable(x.A)) " + forallMacro_help(arity, true) + " else " + forallMacro_help(arity, false) + " } while(0)"; } return (memo[memoindex] = s); } static string forall2Macro_help(int arity, bool convert) { string s, is, var; int i; s += "{"; for (i = 0; i < arity - 1; i++) { is = int2string(i); var = string("_i") + is; s += "jint " + var + ";"; } is = int2string(arity - 1); // ed is the delta to e per iteration, fd is the delta to f s += "jint const ed=PFAST_DIVIDE(stride[" + is + "]*x.sideFactors[" + is + "]," + "x.stride[" + is + "]);" + "jint const fd=PFAST_DIVIDE(stride[" + is + "]*y.sideFactors[" + is + "]," + "y.stride[" + is + "]);"; for (i = 0; i < arity - 1; i++) { is = int2string(i); var = string("_i") + is; s += "for(" + var + "=lo[" + is + "];" + var + "<=hi[" + is + "];" + var + "+=stride[" + is + "]) "; } is = int2string(i); var = string("_i") + is; s += "{jint " + var + "=lo[" + is + "];"; if (convert) { s += "T *e; T *f;"; s += "INDEX_LOCAL(e,TO_LOCAL(x.A)," + quickconv("x", arity) + ");"; s += "INDEX_LOCAL(f,TO_LOCAL(y.A)," + quickconv("y", arity) + ");"; } else { s += "PTR_TO_T e,f;"; s += "INDEX(e,x.A," + quickconv("x", arity) + ");"; s += "INDEX(f,y.A," + quickconv("y", arity) + ");"; } s += "for(;" + var + "<=hi[" + is + "];" + var + "+=stride[" + is + "])"; if (convert) s += "{localbody;INDEX_LOCAL(e,e,ed);INDEX_LOCAL(f,f,fd);}"; else s += "{body;INDEX(e,e,ed);INDEX(f,f,fd);}"; s += "}}"; return s; } static string& forall2Macro(int arity, bool isglobal) { static stringmap memo; string s; string memoindex = int2string(arity) + (isglobal?"GLOBAL":"LOCAL"); string& temp = memo[memoindex]; if (temp != "") return temp; if (!isglobal) { s = string("do{") + forall2Macro_help(arity, false) + " } while(0)"; } else { s = "do { if (isDirectlyAddressable(x.A) && isDirectlyAddressable(y.A)) " + forall2Macro_help(arity, true) + " else " + forall2Macro_help(arity, false) + " } while(0)"; } return (memo[memoindex] = s); } #define D(name, val, stmt) \ f << "#define " << name << ' ' << val << '\n'; \ stmt; \ f << "#undef " << name << '\n'; #define E(name, args, val, stmt) \ f << "#define " << name << "(" << args << ") " << val << '\n'; \ stmt; \ f << "#undef " << name << '\n'; static void instantiateToFile(const TypeNode &type, CfCode &f) { const CtTitaniumArray &cType = static_cast(type.cType()); const CtType &t = type.elementType()->cType(); const bool global = !type.isLocal(); // const char sync = type.sharing() == Nonshared ? '0' : '1'; const int n = type.tiArity(); const char *s = global ? "_ti_global_" : "_ti_"; const AssignKind arrayKind = assignKind(type.elementType()); const AssignType arrayType = assignType(type.elementType()); const bool isAtomic = type.elementType()->isAtomic(); const CtType *arraySliceType; if (n > 1) { PrimitiveLitNode *arity = new PrimitiveLitNode( (int32) (n - 1) ); TypeNode *elem = type.elementType(); TypeNode *sliced = new TitaniumArrayTypeNode( elem, arity ); if (type.isLocal()) sliced = sliced->addModifiers( Common::Local ); arraySliceType = &sliced->cType(); } else arraySliceType = &type.cType(); // arbitrary const CtType *array1DType; const TypeNode *array1DTypeNode; { PrimitiveLitNode *arity = new PrimitiveLitNode( (int32) 1 ); TypeNode *elem = type.elementType(); array1DTypeNode = new TitaniumArrayTypeNode( elem, arity ); if (type.isLocal()) array1DTypeNode = array1DTypeNode->addModifiers( Common::Local ); array1DType = &array1DTypeNode->cType(); } const CtType *array1DPointNType; const TypeNode *array1DPointNTypeNode; { PrimitiveLitNode *arity = new PrimitiveLitNode( (int32) 1 ); TypeNode *elem = type.indexType(); array1DPointNTypeNode = new TitaniumArrayTypeNode( elem, arity ); if (type.isLocal()) array1DPointNTypeNode = array1DPointNTypeNode->addModifiers( Common::Local ); array1DPointNType = &array1DPointNTypeNode->cType(); } type.cType().define(f); type.elementType()->cType().define(f); arraySliceType->define(f); array1DType->define(f); array1DPointNType->define(f); //array1DTypeNode->decl()->includeSelf(f); //array1DPointNTypeNode->decl()->includeSelf(f); RectDomainNDecl[ n - 1 ]->includeSelf(f); DomainNDecl[ n - 1 ]->includeSelf(f); MultiRectADomainNDecl[ n - 1 ]->includeSelf(f); DomainNDecl[ 0 ]->includeSelf(f); const string digits = int2string(n); string PointList = "PointList", RectDomainList = "RectDomainList"; if (type.isLocal()) { PointList = "PointListLocal"; RectDomainList = "RectDomainListLocal"; } D("ti_ARRAY", cType, D("copy_desc_t", s << "copy_desc_" << t << "_" << n << "_t", D("ti_ARRAY_SLICE", *arraySliceType, D("ti_1DARRAY_OF_T", *array1DType, D("ti_1DARRAY_OF_POINT_N", *array1DPointNType, D("ti_RECTDOMAIN", MANGLE_TI_DOMAINS_RECTDOMAIN_TYPE(<<, digits), D("ti_RECTDOMAIN1", MANGLE_TI_DOMAINS_RECTDOMAIN_TYPE(<<, "1"), D("ti_DOMAIN", MANGLE_TI_DOMAINS_DOMAIN_TYPE(<<, digits), D("ti_MRAD", MANGLE_TI_DOMAINS_MRAD_TYPE(<<, digits), D("ti_POINT", MANGLE_TI_DOMAINS_POINT_TYPE(<<, digits), D("POINTN_GET", "POINT" << n << "_GET", D("ti_conv", s << "CONV(" << t << ", " << n << ")", D("ti_get_array_data_ptr", s << "GET_ARRAY_DATA_PTR(" << t << ", " << n << ")", D("ti_get_array_data_ptr_with_domain", s << "GET_ARRAY_DATA_PTR_WITH_DOMAIN(" << t << ", " << n << ")", D("ti_dump", s << "DUMP(" << t << ", " << n << ")", D("ti_read", s << "READ(" << t << ", " << n << ")", D("ti_ptr", s << "PTR(" << t << ", " << n << ")", D("ti_write", s << "WRITE(" << t << ", " << n << ")", D("ti_construct", s << "CONSTRUCT(" << t << ", " << n << ")", D("ti_empty", s << "EMPTY(" << t << ", " << n << ")", D("ti_isnull", s << "ISNULL(" << t << ", " << n << ")", D("ti_equals", s << "EQUALS(" << t << ", " << n << ")", D("ti_printdomain", s << "PRINTDOMAIN(" << t << ", " << n << ")", D("ti_abv_ds", s << "ARRAY_BOUNDS_VIOLATIONds(" << t << ", " << n << ")", D("ti_abv_dsd", s << "ARRAY_BOUNDS_VIOLATIONdsd(" << t << ", " << n << ")", D("ti_boundscheck", s << "BOUNDSCHECK(" << t << ", " << n << ")", D("ti_mayoverlap", s << "MAYOVERLAP(" << t << ", " << n << ")", D("DOMAIN_METHOD", s << "arraymethod_domain(" << t << ", " << n << ")", D("BROADCAST_METHOD", s << "arraymethod_broadcast(" << t << ", " << n << ")", D("UNPACK_METHOD", s << "arraymethod_unpack(" << t << ", " << n << ")", D("PACK_METHOD", s << "arraymethod_pack(" << t << ", " << n << ")", D("COPYINNER_METHOD", s << "arraymethod_copyinner(" << t << ", " << n << ")", D("COPY_METHOD", s << "arraymethod_copy(" << t << ", " << n << ")", D("COPYNB_METHOD", s << "arraymethod_copyNB(" << t << ", " << n << ")", D("COPYNBI_METHOD", s << "arraymethod_copyNBI(" << t << ", " << n << ")", D("COPY_WITHDOMAIN_METHOD", s << "arraymethod_copy_withdomain(" << t << ", " << n << ")", D("COPY_WITHRECTDOMAIN_METHOD", s << "arraymethod_copy_withrectdomain(" << t << ", " << n << ")", D("COPY_WITHPTARRAY_METHOD", s << "arraymethod_copy_withptarray(" << t << ", " << n << ")", D("SCATTER_METHOD", s << "arraymethod_scatter(" << t << ", " << n << ")", D("GATHER_METHOD", s << "arraymethod_gather(" << t << ", " << n << ")", D("ISLOCAL_METHOD", s << "arraymethod_isLocal(" << t << ", " << n << ")", D("REGIONOF_METHOD", s << "arraymethod_regionOf(" << t << ", " << n << ")", D("ISCONTIGUOUS_METHOD", s << "arraymethod_isContiguous(" << t << ", " << n << ")", D("ISCONTIGUOUSOVERDOMAIN_METHOD", s << "arraymethod_isContiguousOverDomain(" << t << ", " << n << ")", D("MAKELOCALANDCONTIGUOUS_METHOD", s << "arraymethod_makeLocalAndContiguous(" << t << ", " << n << ")", D("CREATOR_METHOD", s << "arraymethod_creator(" << t << ", " << n << ")", D("RESTRICT_METHOD", s << "arraymethod_restrict(" << t << ", " << n << ")", D("EXCHANGE_METHOD", s << "arraymethod_exchange(" << t << ", " << n << ")", D("PERMUTE_METHOD", s << "arraymethod_permute(" << t << ", " << n << ")", D("SET_METHOD", s << "arraymethod_set(" << t << ", " << n << ")", D("SLICE_METHOD", s << "arraymethod_slice(" << t << ", " << n << ")", D("TRANSLATE_METHOD", s << "arraymethod_translate(" << t << ", " << n << ")", D("INJECT_METHOD", s << "arraymethod_inject(" << t << ", " << n << ")", D("PROJECT_METHOD", s << "arraymethod_project(" << t << ", " << n << ")", D("READFROMRAF_METHOD", s << "arraymethod_readFromRAF(" << t << ", " << n << ")", D("WRITETORAF_METHOD", s << "arraymethod_writeToRAF(" << t << ", " << n << ")", D("READFROMDIS_METHOD", s << "arraymethod_readFromDIS(" << t << ", " << n << ")", D("WRITETODOS_METHOD", s << "arraymethod_writeToDOS(" << t << ", " << n << ")", D("POINT_INDEX", MANGLE_TI_DOMAINS_POINT_RAWDISPATCH(<<, digits, "o4OBCB", MANGLE_INT_ARG(<<)), D("POINT_SET", MANGLE_TI_DOMAINS_POINT_DISPATCH(<<, digits, "set", MANGLE_INT_ARG(<<) << MANGLE_INT_ARG(<<)), E("RECTDOMAIN_EMPTY", "", "(" << NEW_RECTDOMAIN_EMPTY(<<, digits) << ")", E("RECTDOMAIN_SLICE", "R, k", ((n == 1) ? string("abort()") : string("(") + MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(+, digits, "slice", MANGLE_INT_ARG(+)) + "((R),(k)))"), E("RECTDOMAIN_INTERSECTION", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_RAWDISPATCH(<<, digits, "o2ST", MANGLE_TI_DOMAINS_RECTDOMAIN_ARG(<<, digits)) << "((a), (b)))", E("RECTDOMAIN_EQUAL", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_RAWDISPATCH(<<, digits, "o4EQEQ", MANGLE_TI_DOMAINS_RECTDOMAIN_ARG(<<, digits)) << "((a), (b)))", E("RECTDOMAIN_STRIDE", "a", "((a)." << MANGLE_TI_DOMAINS_RECTDOMAIN_FIELD_ACCESS(<<, "loopStride", digits) << ")", E("RECTDOMAIN_MIN", "a", "((a)." << MANGLE_TI_DOMAINS_RECTDOMAIN_FIELD_ACCESS(<<, "p0", digits) << ")", E("RECTDOMAIN_MAX", "a", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(<<, digits, "max", "") << "((a)))", E("RECTDOMAIN_UPB", "a", "((a)." << MANGLE_TI_DOMAINS_RECTDOMAIN_FIELD_ACCESS(<<, "p1", digits) << ")", E("RECTDOMAIN_ISNULL", "a", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(<<, digits, "isNull", "") << "((a)))", E("RECTDOMAIN_SIZE", "a", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(<<, digits, "size", "") << "((a)))", E("RECTDOMAIN_TRANSLATE", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(<<, digits, "translate", MANGLE_TI_DOMAINS_POINT_ARG(<<, digits)) << "((a), (b)))", E("RECTDOMAIN_PERMUTE", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(<<, digits, "permute", MANGLE_TI_DOMAINS_POINT_ARG(<<, digits)) << "((a), (b)))", E("RECTDOMAIN_MULTIPLY", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_RAWDISPATCH(<<, digits, "o2ST", MANGLE_TI_DOMAINS_POINT_ARG(<<, digits)) << "((a), (b)))", E("RECTDOMAIN_DIVIDE", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_RAWDISPATCH(<<, digits, "o2SL", MANGLE_TI_DOMAINS_POINT_ARG(<<, digits)) << "((a), (b)))", E("RECTDOMAIN_CONTAINS", "a, b", "(" << MANGLE_TI_DOMAINS_RECTDOMAIN_DISPATCH(<<, digits, "contains", MANGLE_TI_DOMAINS_POINT_ARG(<<, digits)) << "((a), (b)))", E("DOMAIN_POINTLIST", "d", MANGLE_TI_DOMAINS_DOMAIN_DISPATCH(<<, digits, PointList, "") << "(d)", E("DOMAIN_RECTDOMAINLIST", "d", MANGLE_TI_DOMAINS_DOMAIN_DISPATCH(<<, digits, RectDomainList, "") << "(d)", D("N_MINUS_1", (n - 1), D("T_string", ('"' + t + '"'), D("T", t, D("ELEMENTS_ARE_ATOMIC", (isAtomic ? 1 : 0), E("BUMP_PTR", "p, delta", "INDEX(p, p, delta)", D("GLOBAL_ARRAY", (global ? 1 : 0), D("GLOBAL_ELEMENTS", (type.elementType()->isLocal() ? 0 : 1), E("assign", "ptr, val", "do { " << type.fencePreWrite() << assignMacro(arrayKind, arrayType, false, !global) << "(ptr, val); " << type.fencePostWrite() << " } while (0)", E("weak_assign", "ptr, val", "do { " << type.fencePreWrite() << "WEAK_" << assignMacro(arrayKind, arrayType, false, !global) << "(ptr, val); " << type.fencePostWrite() << " } while (0)", E("deref", "val, ptr", "do { " << type.fencePreRead() << " DEREF_" << (global?"GLOBAL":"LOCAL") << assignSuffix(arrayType, !global) << "(val, ptr); " << type.fencePostRead() << " } while (0)", D("N", n, E("forall", "e, x, lo, hi, stride, body, localbody", forallMacro(n,global), E("forall2", "e, x, f, y, lo, hi, stride, body, localbody", forall2Macro(n,global), E("setBase", "e, x, f, y", setBaseMacro(n), E("sliceRect", "e, x, f, y, body", sliceRectMacro(n), E("PRINT_FORALL_POINT", "f", printForallPointMacro(n), D("PTR_TO_T", cType.data, f << "#define TI_ARRAY_ADDR_" << (global ? "GLOBAL" : "LOCAL") << '_' << t << '_' << n << "(result, array, index, where) ((result) = " << arrayInternal("PTR", global) << '(' << t << ", " << n << ')' << "(\"(in array access)\" TI_ARRAY_PTR_LOC(where), (array), (index)))\n" /* macro redirects of copy() and copyNBI() to copyinner */ << "#define TI_" << (global ? "GLOBAL_" : "") << "ARRAY_copy_" << t << "_" << n << "(x,y) " << "TI_" << (global ? "GLOBAL_" : "") << "ARRAY_copyinner_" << t << "_" << n << "(x,y,NULL)\n" << "#define TI_" << (global ? "GLOBAL_" : "") << "ARRAY_copyNBI_" << t << "_" << n << "(x,y) " << "TI_" << (global ? "GLOBAL_" : "") << "ARRAY_copyinner_" << t << "_" << n << "(x,y,HANDLE_NBI)\n" << "#include \n" )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))); } static void instantiateArrayCasts( const TypeNode &local, const TypeNode &global, CfCode &f, bool header ) { const CtType &t = local.elementType()->cType(); const string n = int2string(local.tiArity()); if (header) { global.cType().declare(f); local.cType().declare(f); } else { global.cType().define(f); local.cType().define(f); } D("ti_GLOBAL_ARRAY", global.cType(), D("ti_LOCAL_ARRAY", local.cType(), D("ti_cast_to_global", "_ti_arraymethod_cast(" << t << ", " << n << ")", D("ti_cast_to_local", "_ti_global_arraymethod_cast(" << t << ", " << n << ")", f << "#include \n"; )))); } static void instantiatePair( const TypeNode &local, const TypeNode &global, CfCode &code, bool header ) { instantiateToFile( local, code ); instantiateToFile( global, code ); instantiateArrayCasts( local, global, code, header ); } static void instantiateArrays( const TitaniumArrayTypeNode &type ) { if (DEBUG) cout << " adding array <" << type.errorName() << ">\n"; const TypeNode &local = *type.addModifiers(Common::Local); const TypeNode &global = *type.removeModifiers((Common::Modifiers) (Common::Local | Common::LocalInferred)); CfHeader header( global.cType() ); CfSource source( global.cType() , "#define TI_NO_SRCPOS\n"); // prevent GASNet tracing from reporting line numbers inside array library // Create local and global versions of all arrays, whether we need // them or not. This is slightly wasteful. instantiatePair( local, global, header, true ); instantiatePair( local, global, source, false ); } void instantiateArrays(void) { for (ArraySet::const_iterator sweep = arrayTypes.begin(); sweep != arrayTypes.end(); ++sweep) { const TitaniumArrayTypeNode *arrayType = *sweep; if (arrayType->selectedForCodeGen(!bounds_checking)) // use the library versions if available (and we're bounds-checking) instantiateArrays(*arrayType); } }