Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Changeset 217:0806379a5eca

Show
Ignore:
Timestamp:
06/05/08 00:38:36 (7 months ago)
Author:
lindquist
branch:
trunk
Message:

[svn r233] Added: -oq command line option for writing fully qualified object names.
Added: started support for x86 80bit floating point.
Changed: aggregates passed by value now use the llvm 'byval' parameter attribute, also lays ground work for
using other attributes.
Changed: eliminated a lot more std::vectorS, these showed up pretty much at the top when profiling!
Changed: performed other misc. cleanups.
Changed: halt expression now call the new llvm trap intrinsic instead of an assert(0).
Changed: dstress suite now passes -O0 by default, this only eliminates unreferenced globals, which speeds up
linking quite a bit.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dmd/mars.c

    r205 r217  
    203203  -of<filename>  name output file to <filename>\n\ 
    204204  -op            do not strip paths from source file\n\ 
     205  -oq            write object files with fully qualified names\n\ 
    205206  -profile   profile runtime performance of generated code\n\ 
    206207  -quiet         suppress unnecessary messages\n\ 
     
    215216  -version=ident compile in version code identified by ident\n\ 
    216217  -w             enable warnings\n\ 
     218  -fp80          enable 80bit reals on x86 32bit (EXPERIMENTAL)\n\ 
    217219", 
    218220#if WIN32 
     
    398400        else if (strcmp(p + 1, "annotate") == 0) 
    399401            global.params.llvmAnnotate = 1; 
     402        else if (strcmp(p + 1, "fp80") == 0) 
     403            global.params.useFP80 = 1; 
    400404        else if (p[1] == 'o') 
    401405        { 
     
    423427            global.params.preservePaths = 1; 
    424428            break; 
     429 
     430            case 'q': 
     431            if (p[3]) 
     432                goto Lerror; 
     433            global.params.fqnPaths = 1; 
     434            break; 
    425435 
    426436            case 0: 
     
    692702    } 
    693703 
     704    bool is_x86 = false; 
    694705    if (strcmp(global.params.llvmArch,"x86")==0) { 
    695706        VersionCondition::addPredefinedGlobalIdent("X86"); 
     
    699710        tt_arch = "i686"; 
    700711        data_layout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:8"; 
     712        is_x86 = true; 
    701713    } 
    702714    else if (strcmp(global.params.llvmArch,"x86-64")==0) { 
     
    739751    if (global.params.is64bit) { 
    740752        VersionCondition::addPredefinedGlobalIdent("LLVM64"); 
     753    } 
     754 
     755    if (global.params.useFP80) { 
     756        if (!is_x86) { 
     757            error("the -fp80 option is only valid for the x86 32bit architecture"); 
     758            fatal(); 
     759        } 
     760        VersionCondition::addPredefinedGlobalIdent("LLVM_X86_FP80"); 
    741761    } 
    742762 
  • dmd/mars.h

    r159 r217  
    134134    char llvmAnnotate; 
    135135    char *runtimePath; 
     136    char useFP80; 
     137    char fqnPaths; // use fully qualified object names 
    136138}; 
    137139 
  • dmd/mtype.c

    r211 r217  
    25392539    Type *treturn = next ? next->syntaxCopy() : NULL; 
    25402540    Arguments *params = Argument::arraySyntaxCopy(parameters); 
    2541     Type *t = new TypeFunction(params, treturn, varargs, linkage); 
     2541    TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage); 
     2542    t->llvmRetInPtr = llvmRetInPtr; 
     2543    t->llvmUsesThis = llvmUsesThis; 
    25422544    return t; 
    25432545} 
     
    50635065    this->storageClass = storageClass; 
    50645066    this->defaultArg = defaultArg; 
     5067    this->llvmByVal = false; 
    50655068} 
    50665069 
     
    50715074        ident, 
    50725075        defaultArg ? defaultArg->syntaxCopy() : NULL); 
     5076    a->llvmByVal = llvmByVal; 
    50735077    return a; 
    50745078} 
  • dmd/mtype.h

    r211 r217  
    682682    static size_t dim(Arguments *arguments); 
    683683    static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL); 
     684 
     685    // LLVMDC 
     686    bool llvmByVal; 
    684687}; 
    685688 
  • gen/aa.cpp

    r213 r217  
    8787    pkey = DtoBitCast(pkey, funcTy->getParamType(3)); 
    8888 
    89     // build arg vector 
    90     LLSmallVector<LLValue*, 4> args; 
    91     args.push_back(aaval); 
    92     args.push_back(keyti); 
    93     args.push_back(valsize); 
    94     args.push_back(pkey); 
    95  
    9689    // call runtime 
    97     LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.index"); 
     90    LLValue* ret = gIR->ir->CreateCall4(func, aaval, keyti, valsize, pkey, "aa.index"); 
    9891 
    9992    // cast return value 
     
    132125    pkey = DtoBitCast(pkey, funcTy->getParamType(2)); 
    133126 
    134     // build arg vector 
    135     LLSmallVector<LLValue*, 3> args; 
    136     args.push_back(aaval); 
    137     args.push_back(keyti); 
    138     args.push_back(pkey); 
    139  
    140127    // call runtime 
    141     LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.in"); 
     128    LLValue* ret = gIR->ir->CreateCall3(func, aaval, keyti, pkey, "aa.in"); 
    142129 
    143130    // cast return value 
  • gen/arrays.cpp

    r213 r217  
    185185    Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; 
    186186 
    187     std::vector<LLValue*> args; 
     187    LLSmallVector<LLValue*, 4> args; 
    188188    args.push_back(ptr); 
    189189    args.push_back(dim); 
     
    425425 
    426426    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); 
    427     std::vector<LLValue*> llargs; 
    428     llargs.resize(4); 
     427    LLSmallVector<LLValue*, 4> llargs(4); 
    429428    llargs[0] = dstarr; 
    430429    llargs[1] = srcarr; 
    431430    llargs[2] = sz1; 
    432     llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 
     431    llargs[3] = DtoConstInt(0); 
    433432 
    434433    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 
     
    445444 
    446445    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); 
    447     std::vector<LLValue*> llargs; 
    448     llargs.resize(4); 
     446    LLSmallVector<LLValue*, 4> llargs(4); 
    449447    llargs[0] = dstarr; 
    450448    llargs[1] = srcarr; 
    451449    llargs[2] = sz1; 
    452     llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 
     450    llargs[3] = DtoConstInt(0); 
    453451 
    454452    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 
     
    468466 
    469467    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); 
    470     std::vector<LLValue*> llargs; 
    471     llargs.resize(4); 
     468    LLSmallVector<LLValue*,4> llargs(4); 
    472469    llargs[0] = dstarr; 
    473470    llargs[1] = srcarr; 
    474471    llargs[2] = n; 
    475     llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 
     472    llargs[3] = DtoConstInt(0); 
    476473 
    477474    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 
     
    481478LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) 
    482479{ 
    483     std::vector<const LLType*> types; 
    484     types.push_back(dim->getType()); 
    485     types.push_back(ptr->getType()); 
    486     const llvm::StructType* type = llvm::StructType::get(types); 
    487     std::vector<LLConstant*> values; 
    488     values.push_back(dim); 
    489     values.push_back(ptr); 
    490     return llvm::ConstantStruct::get(type,values); 
     480    LLConstant* values[2] = { dim, ptr }; 
     481    return llvm::ConstantStruct::get(values, 2); 
    491482} 
    492483 
     
    497488    LOG_SCOPE; 
    498489 
     490    // typeinfo arg 
     491    LLValue* arrayTypeInfo = DtoTypeInfoOf(arrayType); 
     492 
     493    // dim arg 
     494    assert(DtoType(dim->getType()) == DtoSize_t()); 
     495    LLValue* arrayLen = dim->getRVal(); 
     496 
     497    // get runtime function 
    499498    bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); 
    500499    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" ); 
    501500 
    502     LLSmallVector<LLValue*,2> args; 
    503     args.push_back(DtoTypeInfoOf(arrayType)); 
    504     assert(DtoType(dim->getType()) == DtoSize_t()); 
    505     args.push_back(dim->getRVal()); 
    506  
    507     LLValue* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem"); 
     501    // call allocator 
     502    LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem"); 
     503 
     504    // cast to wanted type 
    508505    const LLType* dstType = DtoType(arrayType)->getContainedType(1); 
    509506    if (newptr->getType() != dstType) 
     
    519516#endif 
    520517 
    521     return new DSliceValue(arrayType, args[1], newptr); 
     518    return new DSliceValue(arrayType, arrayLen, newptr); 
    522519} 
    523520 
     
    543540    args.push_back(newdim->getRVal()); 
    544541    args.push_back(DtoArrayLen(array)); 
     542 
    545543    LLValue* arrPtr = DtoArrayPtr(array); 
    546544    Logger::cout() << "arrPtr = " << *arrPtr << '\n'; 
     
    735733    assert(l_ty->next == r_ty->next); 
    736734    if ((l_ty->ty == Tsarray) || (r_ty->ty == Tsarray)) { 
    737         Type* a_ty = new Type(Tarray, l_ty->next); 
     735        Type* a_ty = l_ty->next->arrayOf(); 
    738736        if (l_ty->ty == Tsarray) 
    739737            l = DtoCastArray(l, a_ty); 
     
    775773    const LLType* pt = fn->getFunctionType()->getParamType(0); 
    776774 
    777     std::vector<LLValue*> args; 
     775    LLSmallVector<LLValue*, 3> args; 
    778776    Logger::cout() << "bitcasting to " << *pt << '\n'; 
    779777    Logger::cout() << *lmem << '\n'; 
     
    800798LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r) 
    801799{ 
    802     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); 
    803     assert(fn); 
    804  
    805800    LLValue* res = DtoArrayEqCmp_impl("_adEq", l, r, true); 
    806801    if (op == TOKnotequal) 
     
    884879        return len; 
    885880 
    886     std::vector<LLValue*> args; 
     881    LLSmallVector<LLValue*, 3> args; 
    887882    args.push_back(len); 
    888883    args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false)); 
  • gen/classes.cpp

    r213 r217  
    797797    { 
    798798        llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); 
    799         std::vector<LLValue*> args; 
    800         args.push_back(tc->sym->ir.irStruct->classInfo); 
    801         mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); 
     799        mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc"); 
    802800        mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); 
    803801    } 
     
    899897    TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); 
    900898 
     899    llvm::PAListPtr palist; 
     900 
    901901    std::vector<LLValue*> ctorargs; 
    902902    ctorargs.push_back(mem); 
     
    911911            a = DtoBitCast(a, aty); 
    912912        ctorargs.push_back(a); 
     913        if (fnarg && fnarg->llvmByVal) 
     914            palist = palist.addAttr(i+2, llvm::ParamAttr::ByVal); // return,this is 2 
    913915    } 
    914916    llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); 
    915917    call->setCallingConv(DtoCallingConv(LINKd)); 
     918    call->setParamAttrs(palist); 
    916919 
    917920    return new DImValue(type, call, false); 
     
    9981001 
    9991002    // Object o 
    1000     LLValue* tmp = val->getRVal(); 
    1001     tmp = DtoBitCast(tmp, funcTy->getParamType(0)); 
    1002     args.push_back(tmp); 
    1003     assert(funcTy->getParamType(0) == tmp->getType()); 
     1003    LLValue* obj = val->getRVal(); 
     1004    obj = DtoBitCast(obj, funcTy->getParamType(0)); 
     1005    assert(funcTy->getParamType(0) == obj->getType()); 
    10041006 
    10051007    // ClassInfo c 
     
    10071009    DtoForceDeclareDsymbol(to->sym); 
    10081010    assert(to->sym->ir.irStruct->classInfo); 
    1009     tmp = to->sym->ir.irStruct->classInfo; 
     1011    LLValue* cinfo = to->sym->ir.irStruct->classInfo; 
    10101012    // unfortunately this is needed as the implementation of object differs somehow from the declaration 
    10111013    // this could happen in user code as well :/ 
    1012     tmp = DtoBitCast(tmp, funcTy->getParamType(1)); 
    1013     args.push_back(tmp); 
    1014     assert(funcTy->getParamType(1) == tmp->getType()); 
     1014    cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); 
     1015    assert(funcTy->getParamType(1) == cinfo->getType()); 
    10151016 
    10161017    // call it 
    1017     LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); 
     1018    LLValue* ret = gIR->ir->CreateCall2(func, obj, cinfo, "tmp"); 
    10181019 
    10191020    // cast return value 
     
    10651066 
    10661067    // void* p 
    1067     LLValue* tmp = val->getRVal(); 
    1068     tmp = DtoBitCast(tmp, funcTy->getParamType(0)); 
    1069     args.push_back(tmp); 
     1068    LLValue* ptr = val->getRVal(); 
     1069    ptr = DtoBitCast(ptr, funcTy->getParamType(0)); 
    10701070 
    10711071    // ClassInfo c 
     
    10731073    DtoForceDeclareDsymbol(to->sym); 
    10741074    assert(to->sym->ir.irStruct->classInfo); 
    1075     tmp = to->sym->ir.irStruct->classInfo; 
     1075    LLValue* cinfo = to->sym->ir.irStruct->classInfo; 
    10761076    // unfortunately this is needed as the implementation of object differs somehow from the declaration 
    10771077    // this could happen in user code as well :/ 
    1078     tmp = DtoBitCast(tmp, funcTy->getParamType(1)); 
    1079     args.push_back(tmp); 
     1078    cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); 
    10801079 
    10811080    // call it 
    1082     LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); 
     1081    LLValue* ret = gIR->ir->CreateCall2(func, ptr, cinfo, "tmp"); 
    10831082 
    10841083    // cast return value 
     
    11281127////////////////////////////////////////////////////////////////////////////////////////// 
    11291128 
    1130 LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs) 
     1129LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, DStructIndexVector& idxs) 
    11311130{ 
    11321131    Logger::println("checking for offset %u type %s:", os, t->toChars()); 
     
    11581157            idxs.push_back(vd->ir.irField->index + dataoffset); 
    11591158            //Logger::cout() << "indexing: " << *ptr << '\n'; 
    1160             ptr = DtoGEP(ptr, idxs, "tmp"); 
     1159            ptr = DtoGEPi(ptr, idxs, "tmp"); 
    11611160            if (ptr->getType() != llt) 
    11621161                ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 
     
    11731172            if (vd->ir.irField->indexOffset) { 
    11741173                Logger::println("has union field offset"); 
    1175                 ptr = DtoGEP(ptr, idxs, "tmp"); 
     1174                ptr = DtoGEPi(ptr, idxs, "tmp"); 
    11761175                if (ptr->getType() != llt) 
    11771176                    ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 
    11781177                ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); 
    1179                 std::vector<unsigned> tmp; 
     1178                DStructIndexVector tmp; 
    11801179                return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 
    11811180            } 
     
    11841183                if (ptr->getType() != sty) { 
    11851184                    ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); 
    1186                     std::vector<unsigned> tmp; 
     1185                    DStructIndexVector tmp; 
    11871186                    return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 
    11881187                } 
  • gen/classes.h

    r213 r217  
    11#ifndef LLVMDC_GEN_CLASSES_H 
    22#define LLVMDC_GEN_CLASSES_H 
     3 
     4#include "gen/structs.h" 
    35 
    46/** 
     
    3638DValue* DtoDynamicCastInterface(DValue* val, Type* to); 
    3739 
    38 LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs); 
     40LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, DStructIndexVector& idxs); 
    3941 
    4042LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl); 
  • gen/complex.cpp

    r213 r217  
    2929    const LLType* base; 
    3030    if (ty == Tcomplex32) { 
    31         return llvm::Type::FloatTy; 
    32     } 
    33     else if (ty == Tcomplex64 || ty == Tcomplex80) { 
    34         return llvm::Type::DoubleTy; 
     31        return LLType::FloatTy; 
     32    } 
     33    else if (ty == Tcomplex64) { 
     34        return LLType::DoubleTy; 
     35    } 
     36    else if (ty == Tcomplex80) { 
     37        return (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy; 
    3538    } 
    3639    else { 
     
    6164    llvm::ConstantFP* fim; 
    6265 
    63     const LLType* base
     66    Type* base = 0
    6467 
    6568    if (ty == Tcomplex32) { 
    66         fre = DtoConstFP(Type::tfloat32, re); 
    67         fim = DtoConstFP(Type::tfloat32, im); 
    68         base = llvm::Type::FloatTy; 
    69     } 
    70     else if (ty == Tcomplex64 || ty == Tcomplex80) { 
    71         fre = DtoConstFP(Type::tfloat64, re); 
    72         fim = DtoConstFP(Type::tfloat64, im); 
    73         base = llvm::Type::DoubleTy; 
    74     } 
    75     else 
    76     assert(0); 
     69        base = Type::tfloat32; 
     70    } 
     71    else if (ty == Tcomplex64) { 
     72        base = Type::tfloat64; 
     73    } 
     74    else if (ty == Tcomplex80) { 
     75        base = (global.params.useFP80) ? Type::tfloat80 : Type::tfloat64; 
     76    } 
    7777 
    7878    std::vector<LLConstant*> inits; 
    79     inits.push_back(fre); 
    80     inits.push_back(fim); 
     79    inits.push_back(DtoConstFP(base, re)); 
     80    inits.push_back(DtoConstFP(base, im)); 
     81 
    8182    return llvm::ConstantStruct::get(DtoComplexType(_ty), inits); 
    82 } 
    83  
    84 LLConstant* DtoUndefComplex(Type* _ty) 
    85 { 
    86     assert(0); 
    87     TY ty = DtoDType(_ty)->ty; 
    88     const LLType* base; 
    89     if (ty == Tcomplex32) { 
    90         base = llvm::Type::FloatTy; 
    91     } 
    92     else if (ty == Tcomplex64 || ty == Tcomplex80) { 
    93         base = llvm::Type::DoubleTy; 
    94     } 
    95     else 
    96     assert(0); 
    97  
    98     std::vector<LLConstant*> inits; 
    99     inits.push_back(llvm::UndefValue::get(base)); 
    100     inits.push_back(llvm::UndefValue::get(base)); 
    101  
    102     const llvm::VectorType* vt = llvm::VectorType::get(base, 2); 
    103     return llvm::ConstantVector::get(vt, inits); 
    10483} 
    10584 
     
    136115    LLConstant* zero; 
    137116    if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32) 
    138         zero = llvm::ConstantFP::get(llvm::APFloat(0.0f)); 
    139     else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64 || ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) 
    140         zero = llvm::ConstantFP::get(llvm::APFloat(0.0)); 
     117        zero = LLConstant::getNullValue(DtoType(Type::tfloat32)); // llvm::ConstantFP::get(llvm::APFloat(0.0f)); 
     118    else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64) 
     119        zero = LLConstant::getNullValue(DtoType(Type::tfloat64)); 
     120    else if (ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) 
     121        zero = LLConstant::getNullValue(DtoType((global.params.useFP80)?Type::tfloat80:Type::tfloat64)); 
    141122 
    142123    if (t->isimaginary()) { 
  • gen/complex.h

    r213 r217  
    33 
    44const llvm::StructType* DtoComplexType(Type* t); 
    5 const llvm::Type* DtoComplexBaseType(Type* t); 
     5const LLType* DtoComplexBaseType(Type* t); 
    66 
    77LLConstant* DtoConstComplex(Type* t, LLConstant* re, LLConstant* im); 
    88LLConstant* DtoConstComplex(Type* t, long double re, long double im); 
    9 LLConstant* DtoUndefComplex(Type* _ty); 
    109 
    1110LLConstant* DtoComplexShuffleMask(unsigned a, unsigned b); 
  • gen/functions.cpp

    r215 r217  
    5252        assert(rt); 
    5353        Type* rtfin = DtoDType(rt); 
    54         if (DtoIsPassedByRef(rt)) { 
     54        if (DtoIsReturnedInArg(rt)) { 
    5555            rettype = getPtrToType(DtoType(rt)); 
    5656            actualRettype = llvm::Type::VoidTy; 
     
    9595    size_t n = Argument::dim(f->parameters); 
    9696 
     97    int nbyval = 0; 
     98 
     99    llvm::PAListPtr palist; 
     100 
    97101    for (int i=0; i < n; ++i) { 
    98102        Argument* arg = Argument::getNth(f->parameters, i); 
     
    101105        assert(argT); 
    102106 
     107        bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); 
     108 
    103109        const LLType* at = DtoType(argT); 
    104110        if (isaStruct(at)) { 
    105111            Logger::println("struct param"); 
    106112            paramvec.push_back(getPtrToType(at)); 
     113            arg->llvmByVal = !refOrOut; 
    107114        } 
    108115        else if (isaArray(at)) { 
     
    111118            //paramvec.push_back(getPtrToType(at->getContainedType(0))); 
    112119            paramvec.push_back(getPtrToType(at)); 
     120            arg->llvmByVal = !refOrOut; 
    113121        } 
    114122        else if (llvm::isa<llvm::OpaqueType>(at)) { 
     
    118126        } 
    119127        else { 
    120             if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) { 
     128            if (refOrOut) { 
    121129                Logger::println("by ref param"); 
    122130                at = getPtrToType(at); 
     
    127135            paramvec.push_back(at); 
    128136        } 
    129     } 
     137 
     138        if (arg->llvmByVal) 
     139            nbyval++; 
     140    } 
     141 
     142    //warning("set %d byval args for type: %s", nbyval, f->toChars()); 
    130143 
    131144    // construct function type 
     
    136149    f->llvmUsesThis = usesthis; 
    137150 
    138     //if (!f->ir.type) 
    139         f->ir.type = new llvm::PATypeHolder(functype); 
    140     //else 
    141         //assert(functype == f->ir.type->get()); 
     151    f->ir.type = new llvm::PATypeHolder(functype); 
    142152 
    143153    return functype; 
     
    378388    fdecl->ir.irFunc->func = func; 
    379389    assert(llvm::isa<llvm::FunctionType>(f->ir.type->get())); 
     390 
     391    // parameter attributes 
     392    if (f->parameters) 
     393    { 
     394        int llidx = 1; 
     395        if (f->llvmRetInPtr) ++llidx; 
     396        if (f->llvmUsesThis) ++llidx; 
     397        if (f->linkage == LINKd && f->varargs == 1) 
     398            llidx += 2; 
     399 
     400        int funcNumArgs = func->getArgumentList().size(); 
     401        std::vector<llvm::ParamAttrsWithIndex> attrs; 
     402        int k = 0; 
     403 
     404        int nbyval = 0; 
     405 
     406        for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) 
     407        { 
     408            Argument* fnarg = (Argument*)f->parameters->data[k]; 
     409            assert(fnarg); 
     410            if (fnarg->llvmByVal) 
     411            { 
     412                llvm::ParamAttrsWithIndex PAWI; 
     413                PAWI.Index = llidx; 
     414                PAWI.Attrs = llvm::ParamAttr::ByVal; 
     415                attrs.push_back(PAWI); 
     416                nbyval++; 
     417            } 
     418        } 
     419 
     420        //warning("set %d byval args for function: %s", nbyval, func->getName().c_str()); 
     421 
     422        if (nbyval) { 
     423            llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); 
     424            func->setParamAttrs(palist); 
     425        } 
     426    } 
    380427 
    381428    // main 
     
    776823            arg = new DImValue(argexp->type, arg->getRVal(), false); 
    777824    } 
    778     // aggregate arg 
    779     else if (DtoIsPassedByRef(argexp->type)
     825    // byval arg, but expr has no storage yet 
     826    else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())
    780827    { 
    781828        LLValue* alloc = new llvm::AllocaInst(DtoType(argexp->type), "tmpparam", gIR->topallocapoint()); 
     
    783830        DtoAssign(vv, arg); 
    784831        arg = vv; 
    785     } 
    786     // normal arg (basic/value type) 
    787     else 
    788     { 
    789         // nothing to do 
    790832    } 
    791833 
  • gen/statements.cpp

    r213 r217  
    9393            emit_finallyblocks(p, enclosingtryfinally, NULL); 
    9494 
    95             if (gIR->func()->inVolatile) { 
     95            if (f->inVolatile) { 
    9696                // store-load barrier 
    9797                DtoMemoryBarrier(false, false, true, false); 
     
    129129    else 
    130130    { 
    131         if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { 
    132             emit_finallyblocks(p, enclosingtryfinally, NULL); 
    133  
    134             if (gIR->func()->inVolatile) { 
    135                 // store-load barrier 
    136                 DtoMemoryBarrier(false, false, true, false); 
    137             } 
    138  
    139             if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 
    140             llvm::ReturnInst::Create(p->scopebb()); 
    141         } 
    142         else { 
    143             assert(0); // why should this ever happen? 
    144             new llvm::UnreachableInst(p->scopebb()); 
    145         } 
     131        assert(p->topfunc()->getReturnType() == llvm::Type::VoidTy); 
     132        emit_finallyblocks(p, enclosingtryfinally, NULL); 
     133 
     134        if (gIR->func()->inVolatile) { 
     135            // store-load barrier 
     136            DtoMemoryBarrier(false, false, true, false); 
     137        } 
     138 
     139        if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 
     140        llvm::ReturnInst::Create(p->scopebb()); 
    146141    } 
    147142} 
     
    617612 
    618613    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); 
    619     std::vector<LLValue*> args; 
     614 
    620615    Logger::cout() << *table->getType() << '\n'; 
    621616    Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n'; 
    622617    assert(table->getType() == fn->getFunctionType()->getParamType(0)); 
    623     args.push_back(table); 
    624618 
    625619    DValue* val = e->toElem(gIR); 
     
    637631    } 
    638632    assert(llval->getType() == fn->getFunctionType()->getParamType(1)); 
    639     args.push_back(llval); 
    640  
    641     return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); 
     633 
     634    return gIR->ir->CreateCall2(fn, table, llval, "tmp"); 
    642635} 
    643636 
  • gen/structs.cpp

    r213 r217  
    106106////////////////////////////////////////////////////////////////////////////////////////// 
    107107 
    108 LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) 
     108LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs) 
    109109{ 
    110110    Logger::println("checking for offset %u type %s:", os, t->toChars()); 
     
    128128        if (os == vd->offset && vdtype == t) { 
    129129            idxs.push_back(vd->ir.irField->index); 
    130             ptr = DtoGEP(ptr, idxs, "tmp"); 
     130            ptr = DtoGEPi(ptr, idxs, "tmp"); 
    131131            if (ptr->getType() != llt) 
    132132                ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 
     
    141141            if (vd->ir.irField->indexOffset) { 
    142142                Logger::println("has union field offset"); 
    143                 ptr = DtoGEP(ptr, idxs, "tmp"); 
     143                ptr = DtoGEPi(ptr, idxs, "tmp"); 
    144144                if (ptr->getType() != llt) 
    145145                    ptr = DtoBitCast(ptr, llt); 
    146146                ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); 
    147                 std::vector<unsigned> tmp; 
     147                DStructIndexVector tmp; 
    148148                return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 
    149149            } 
     
    152152                if (ptr->getType() != sty) { 
    153153                    ptr = DtoBitCast(ptr, sty); 
    154                     std::vector<unsigned> tmp; 
     154                    DStructIndexVector tmp; 
    155155                    return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 
    156156                } 
  • gen/structs.h

    r213 r217  
    3131void DtoDefineStruct(StructDeclaration* sd); 
    3232 
    33 LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs); 
     33typedef LLSmallVector<unsigned, 3> DStructIndexVector; 
     34LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs); 
    3435 
    3536struct DUnionField 
  • gen/todebug.cpp

    r213 r217  
    197197void DtoDwarfStopPoint(unsigned ln) 
    198198{ 
    199     std::vector<LLValue*> args; 
     199    LLSmallVector<LLValue*,3> args; 
    200200    args.push_back(DtoConstUint(ln)); 
    201201    args.push_back(DtoConstUint(0)); 
  • gen/toir.cpp

    r215 r217  
    619619 
    620620            TypeStruct* ts = (TypeStruct*)e1next; 
    621             std::vector<unsigned> offsets; 
     621            DStructIndexVector offsets; 
    622622            LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); 
    623623            return new DFieldValue(type, v, true); 
     
    10191019    bool isInPlace = false; 
    10201020 
     1021    // attrs 
     1022    llvm::PAListPtr palist; 
     1023 
    10211024    // hidden struct return arguments 
     1025    // TODO: use sret param attr 
    10221026    if (retinptr) { 
    10231027        if (topexp && topexp->e2 == this) { 
     
    11681172            DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); 
    11691173            llargs[j] = argval->getRVal(); 
     1174        #if USE_BYVAL 
     1175            if (fnarg->llvmByVal) 
     1176                palist = palist.addAttr(j, llvm::ParamAttr::ByVal); 
     1177        #endif 
    11701178            j++; 
    11711179        } 
     
    11881196            } 
    11891197 
     1198        #if USE_BYVAL 
     1199            if (fnarg && fnarg->llvmByVal) 
     1200                palist = palist.addAttr(j+1, llvm::ParamAttr::ByVal); 
     1201        #endif 
     1202 
    11901203            // this hack is necessary :/ 
    11911204            if (dfn && dfn->func && dfn->func->runTimeHack) { 
     
    12461259    } 
    12471260 
     1261    // param attrs 
     1262    call->setParamAttrs(palist); 
     1263 
    12481264    return new DImValue(type, retllval, isInPlace); 
    12491265} 
     
    13121328            } 
    13131329            else { 
    1314                 std::vector<unsigned> dst; 
     1330                DStructIndexVector dst; 
    13151331                varmem = DtoIndexStruct(llvalue,vdt->sym, tnext, offset, dst); 
    13161332            } 
     
    14301446            LLValue* src = l->getRVal(); 
    14311447 
    1432             std::vector<unsigned> vdoffsets; 
     1448            DStructIndexVector vdoffsets; 
    14331449            arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); 
    14341450        } 
     
    14391455            LLValue* src = l->getRVal(); 
    14401456 
    1441             std::vector<unsigned> vdoffsets; 
     1457            DStructIndexVector vdoffsets; 
    14421458            arrptr = DtoIndexClass(src, tc->sym, vd->type, vd->offset, vdoffsets); 
    14431459 
     
    22562272    LOG_SCOPE; 
    22572273 
    2258     DtoAssert(&loc, NULL); 
     2274    // call the new (?) trap intrinsic 
     2275    p->ir->CreateCall(GET_INTRINSIC_DECL(trap),""); 
    22592276 
    22602277    new llvm::UnreachableInst(p->scopebb()); 
  • gen/tollvm.cpp

    r213 r217  
    2121 
    2222bool DtoIsPassedByRef(Type* type) 
     23{ 
     24    Type* typ = DtoDType(type); 
     25    TY t = typ->ty; 
     26    return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); 
     27} 
     28 
     29bool DtoIsReturnedInArg(Type* type) 
    2330{ 
    2431    Type* typ = DtoDType(type); 
     
    6875    case Tfloat64: 
    6976    case Timaginary64: 
     77        return llvm::Type::DoubleTy; 
    7078    case Tfloat80: 
    7179    case Timaginary80: 
    72         return llvm::Type::DoubleTy; 
     80        return (global.params.useFP80) ? llvm::Type::X86_FP80Ty : llvm::Type::DoubleTy; 
    7381 
    7482    // complex 
     
    591599////////////////////////////////////////////////////////////////////////////////////////// 
    592600 
    593 LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const std::string& var, llvm::BasicBlock* bb) 
    594 { 
    595     std::vector<LLValue*> v(2); 
     601LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb) 
     602{ 
     603    LLSmallVector<LLValue*,2> v(2); 
    596604    v[0] = i0; 
    597605    v[1] = i1; 
    598     Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; 
    599606    return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); 
    600607} 
     
    602609////////////////////////////////////////////////////////////////////////////////////////// 
    603610 
    604 LLValue* DtoGEP(LLValue* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) 
     611LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb) 
    605612{ 
    606613    size_t n = src.size(); 
    607     std::vector<LLValue*> dst(n, NULL); 
    608     //std::ostream& ostr = Logger::cout(); 
    609     //ostr << "indices for '" << *ptr << "':"; 
    610     for (size_t i=0; i<n; ++i) 
    611     { 
    612         //ostr << ' ' << i; 
    613         dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); 
    614     } 
    615     //ostr << '\n';*/ 
     614    LLSmallVector<LLValue*, 3> dst(n); 
     615 
     616