diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp index 7ff729daf3..1f3ccd93a6 100644 --- a/driver/cl_options.cpp +++ b/driver/cl_options.cpp @@ -258,7 +258,7 @@ static cl::list linkerSwitches("L", cl::opt moduleDepsFile("deps", cl::desc("Write module dependencies to filename"), cl::value_desc("filename")); - + cl::opt mArch("march", cl::desc("Architecture to generate code for:")); diff --git a/gen/aa.cpp b/gen/aa.cpp index ab1c01ec77..bc4d692772 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -87,7 +87,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) if (lvalue) { // valuesize param LLValue* valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type))); - + ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index").getInstruction(); } else { ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.index").getInstruction(); @@ -275,7 +275,7 @@ LLValue* DtoAAEquals(Loc& loc, TOK op, DValue* l, DValue* r) #else llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaEq"); LLFunctionType* funcTy = func->getFunctionType(); - + LLValue* aaval = DtoBitCast(l->getRVal(), funcTy->getParamType(0)); LLValue* abval = DtoBitCast(r->getRVal(), funcTy->getParamType(1)); LLValue* aaTypeInfo = DtoTypeInfoOf(t); diff --git a/gen/binops.cpp b/gen/binops.cpp index 098171ef61..d4eeeb1581 100644 --- a/gen/binops.cpp +++ b/gen/binops.cpp @@ -26,13 +26,13 @@ DValue* DtoBinAdd(DValue* lhs, DValue* rhs) LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); - + LLValue* res; if (t->isfloating()) res = gIR->ir->CreateFAdd(l, r, "tmp"); else res = gIR->ir->CreateAdd(l, r, "tmp"); - + return new DImValue( t, res ); } @@ -44,13 +44,13 @@ DValue* DtoBinSub(DValue* lhs, DValue* rhs) LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); - + LLValue* res; if (t->isfloating()) res = gIR->ir->CreateFSub(l, r, "tmp"); else res = gIR->ir->CreateSub(l, r, "tmp"); - + return new DImValue( t, res ); } @@ -62,7 +62,7 @@ DValue* DtoBinMul(Type* targettype, DValue* lhs, DValue* rhs) LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); - + LLValue* res; if (t->isfloating()) res = gIR->ir->CreateFMul(l, r, "tmp"); @@ -79,7 +79,7 @@ DValue* DtoBinDiv(Type* targettype, DValue* lhs, DValue* rhs) LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); - + LLValue* res; if (t->isfloating()) res = gIR->ir->CreateFDiv(l, r, "tmp"); @@ -129,7 +129,7 @@ LLValue* DtoBinNumericEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op) Logger::println("floating"); res = DtoBinFloatsEquals(loc, lhs, rhs, op); } - + assert(res); return res; } diff --git a/gen/classes.cpp b/gen/classes.cpp index de904edc4e..f06ee792ab 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -305,7 +305,7 @@ DValue* DtoCastClass(DValue* val, Type* _to) IrTypeClass* typeclass = stripModifiers(fc)->irtype->isClass(); // find interface impl - + size_t i_index = typeclass->getInterfaceIndex(it); assert(i_index != ~0 && "requesting interface that is not implemented by this class"); diff --git a/gen/complex.cpp b/gen/complex.cpp index 6c01e3d6d7..cc00afb83c 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -220,7 +220,7 @@ DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) res_re = lhs_re; else // either rhs_re or no re at all (then use any) res_re = rhs_re; - + if(lhs_im && rhs_im) res_im = gIR->ir->CreateFAdd(lhs_im, rhs_im, "tmp"); else if(lhs_im) @@ -250,7 +250,7 @@ DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) res_re = lhs_re; else // either rhs_re or no re at all (then use any) res_re = gIR->ir->CreateFNeg(rhs_re, "neg"); - + if(lhs_im && rhs_im) res_im = gIR->ir->CreateFSub(lhs_im, rhs_im, "tmp"); else if(lhs_im) diff --git a/gen/declarations.cpp b/gen/declarations.cpp index 8d5a5b027c..b7d08ff065 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -171,7 +171,7 @@ void VarDeclaration::codegen(Ir* p) #if LDC_LLVM_VER >= 302 // FIXME: clang uses a command line option for the thread model LLGlobalVariable* gvar = new LLGlobalVariable(*gIR->module, _type, _isconst, - DtoLinkage(this), NULL, _name, 0, + DtoLinkage(this), NULL, _name, 0, isThreadlocal() ? LLGlobalVariable::GeneralDynamicTLSModel : LLGlobalVariable::NotThreadLocal); #else diff --git a/gen/functions.cpp b/gen/functions.cpp index 1912d350d6..ac339a7ea8 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -277,22 +277,22 @@ LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl) assert(tinst); Objects& objs = tinst->tdtypes; - assert(objs.dim == 3); + assert(objs.dim == 3); Expression* a0 = isExpression(objs[0]); assert(a0); StringExp* strexp = a0->toString(); assert(strexp); assert(strexp->sz == 1); - std::string code(static_cast(strexp->string), strexp->len); + std::string code(static_cast(strexp->string), strexp->len); Type* ret = isType(objs[1]); assert(ret); - + Tuple* a2 = isTuple(objs[2]); assert(a2); Objects& arg_types = a2->objects; - + std::string str; llvm::raw_string_ostream stream(str); stream << "define " << *DtoType(ret) << " @" << mangled_name << "("; @@ -303,34 +303,34 @@ LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl) //assert(ty); if(!ty) { - error(tinst->loc, + error(tinst->loc, "All parameters of a template defined with pragma llvm_inline_ir, except for the first one, should be types"); fatal(); } stream << *DtoType(ty); - + i++; if(i >= arg_types.dim) break; - + stream << ", "; } if(ret->ty == Tvoid) - code.append("\nret void"); - + code.append("\nret void"); + stream << ")\n{\n" << code << "\n}"; - + llvm::SMDiagnostic err; llvm::ParseAssemblyString(stream.str().c_str(), gIR->module, err, gIR->context()); std::string errstr = err.getMessage(); if(errstr != "") - error(tinst->loc, - "can't parse inline LLVM IR:\n%s\n%s\n%s\nThe input string was: \n%s", - err.getLineContents().c_str(), - (std::string(err.getColumnNo(), ' ') + '^').c_str(), + error(tinst->loc, + "can't parse inline LLVM IR:\n%s\n%s\n%s\nThe input string was: \n%s", + err.getLineContents().c_str(), + (std::string(err.getColumnNo(), ' ') + '^').c_str(), errstr.c_str(), stream.str().c_str()); - + LLFunction* fun = gIR->module->getFunction(mangled_name); fun->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage); #if LDC_LLVM_VER >= 302 @@ -589,7 +589,7 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati if (attrs[j].Index == curr.Index) { #if LDC_LLVM_VER >= 302 attrs[j].Attrs = llvm::Attributes::get( - gIR->context(), + gIR->context(), llvm::AttrBuilder(attrs[j].Attrs).addAttributes(curr.Attrs)); #else attrs[j].Attrs |= curr.Attrs; @@ -665,7 +665,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) LLFunction* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); if (!func) { if(fdecl->llvmInternal == LLVMinline_ir) - func = DtoInlineIRFunction(fdecl); + func = DtoInlineIRFunction(fdecl); else func = LLFunction::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module); } else if (func->getFunctionType() != functype) { diff --git a/gen/irstate.h b/gen/irstate.h index 009b8238ee..cde25f24b5 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -72,7 +72,7 @@ struct IRScope IRScope(); IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e); - + const IRScope& operator=(const IRScope& rhs); #if DMDV2 @@ -89,7 +89,7 @@ struct IRBuilderHelper struct IRAsmStmt { - IRAsmStmt() + IRAsmStmt() : isBranchToLabel(NULL) {} std::string code; @@ -202,7 +202,7 @@ struct IRState GatesList sharedGates; #endif FuncDeclList unitTests; - + // all template instances that had members emitted // currently only filled for singleobj // used to make sure the complete template instance gets emitted in the diff --git a/gen/llvmcompat.cpp b/gen/llvmcompat.cpp index bc4adc5d22..96bd86f6d0 100644 --- a/gen/llvmcompat.cpp +++ b/gen/llvmcompat.cpp @@ -93,7 +93,7 @@ Triple llvm::Triple__get64BitArchVariant(const std::string& triple) { return T; } -static void appendToGlobalArray(const char *Array, +static void appendToGlobalArray(const char *Array, Module &M, Function *F, int Priority) { IRBuilder<> IRB(M.getContext()); FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 9be258bb74..0852496a43 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -852,7 +852,7 @@ DValue* DtoCast(Loc& loc, DValue* val, Type* to) if (fromtype->ty == Tvector) { return DtoCastVector(loc, val, to); } - else + else #endif if (fromtype->isintegral()) { return DtoCastInt(loc, val, to); diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index f05e2d3559..a191adcac5 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -32,7 +32,7 @@ struct EnclosingTryFinally : EnclosingHandler TryFinallyStatement* tf; llvm::BasicBlock* landingPad; void emitCode(IRState* p); - EnclosingTryFinally(TryFinallyStatement* _tf, llvm::BasicBlock* _pad) + EnclosingTryFinally(TryFinallyStatement* _tf, llvm::BasicBlock* _pad) : tf(_tf), landingPad(_pad) {} }; struct EnclosingVolatile : EnclosingHandler diff --git a/gen/metadata.h b/gen/metadata.h index 394ec8f769..6599a6a1d4 100644 --- a/gen/metadata.h +++ b/gen/metadata.h @@ -38,9 +38,9 @@ inline MDNodeField* MD_GetElement(llvm::MDNode* N, unsigned i) { /// (Its name will be TD_PREFIX ~ ) enum TypeDataFields { TD_Confirm, /// The TypeInfo this node is for. - + TD_Type, /// A value of the LLVM type corresponding to this D type - + // Must be kept last: TD_NumFields /// The number of fields in TypeInfo metadata }; @@ -55,7 +55,7 @@ enum ClassDataFields { CD_BodyType, /// A value of the LLVM type corresponding to the class body. CD_Finalize, /// True if this class (or a base class) has a destructor. CD_CustomDelete,/// True if this class has an overridden delete operator. - + // Must be kept last CD_NumFields /// The number of fields in ClassInfo metadata }; diff --git a/gen/passes/GarbageCollect2Stack.cpp b/gen/passes/GarbageCollect2Stack.cpp index 30a2c4ed03..aa658a73df 100644 --- a/gen/passes/GarbageCollect2Stack.cpp +++ b/gen/passes/GarbageCollect2Stack.cpp @@ -52,7 +52,7 @@ namespace { const Module& M; CallGraph* CG; CallGraphNode* CGNode; - + const Type* getTypeFor(Value* typeinfo) const; }; } @@ -64,14 +64,14 @@ namespace { void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len, const Analysis& A) { Dst = B.CreateBitCast(Dst, PointerType::getUnqual(B.getInt8Ty())); - + Module *M = B.GetInsertBlock()->getParent()->getParent(); const Type* intTy = Len->getType(); const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); const Type *Tys[2] ={VoidPtrTy, intTy}; Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); Value *Align = ConstantInt::get(B.getInt32Ty(), 1); - + CallSite CS = B.CreateCall5(MemSet, Dst, Val, Len, Align, B.getFalse()); if (A.CGNode) A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(MemSet)); @@ -91,11 +91,11 @@ namespace { class FunctionInfo { protected: const Type* Ty; - + public: unsigned TypeInfoArgNr; bool SafeToDelete; - + // Analyze the current call, filling in some fields. Returns true if // this is an allocation we can stack-allocate. virtual bool analyze(CallSite CS, const Analysis& A) { @@ -103,25 +103,25 @@ namespace { Ty = A.getTypeFor(TypeInfo); return (Ty != NULL); } - + // Returns the alloca to replace this call. // It will always be inserted before the call. virtual AllocaInst* promote(CallSite CS, IRBuilder<>& B, const Analysis& A) { NumGcToStack++; - + Instruction* Begin = CS.getCaller()->getEntryBlock().begin(); return new AllocaInst(Ty, ".nongc_mem", Begin); // FIXME: align? } - + FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete) : TypeInfoArgNr(typeInfoArgNr), SafeToDelete(safeToDelete) {} }; - + class ArrayFI : public FunctionInfo { Value* arrSize; int ArrSizeArgNr; bool Initialized; - + public: ArrayFI(unsigned tiArgNr, bool safeToDelete, bool initialized, unsigned arrSizeArgNr) @@ -129,11 +129,11 @@ namespace { ArrSizeArgNr(arrSizeArgNr), Initialized(initialized) {} - + virtual bool analyze(CallSite CS, const Analysis& A) { if (!FunctionInfo::analyze(CS, A)) return false; - + arrSize = CS.getArgument(ArrSizeArgNr); const IntegerType* SizeType = dyn_cast(arrSize->getType()); @@ -158,7 +158,7 @@ namespace { Ty = PtrTy->getElementType(); return true; } - + virtual AllocaInst* promote(CallSite CS, IRBuilder<>& B, const Analysis& A) { IRBuilder<> Builder = B; // If the allocation is of constant size it's best to put it in the @@ -174,11 +174,11 @@ namespace { } else { NumToDynSize++; } - + // Convert array size to 32 bits if necessary Value* count = Builder.CreateIntCast(arrSize, Builder.getInt32Ty(), false); AllocaInst* alloca = Builder.CreateAlloca(Ty, count, ".nongc_mem"); // FIXME: align? - + if (Initialized) { // For now, only zero-init is supported. uint64_t size = A.TD.getTypeStoreSize(Ty); @@ -188,11 +188,11 @@ namespace { Value* Size = B.CreateMul(TypeSize, arrSize); EmitMemZero(B, alloca, Size, A); } - + return alloca; } }; - + // FunctionInfo for _d_allocclass class AllocClassFI : public FunctionInfo { public: @@ -226,17 +226,17 @@ namespace { Constant* hasCustomDelete = dyn_cast(MD_GetElement(node, CD_CustomDelete)); if (hasDestructor == NULL || hasCustomDelete == NULL) return false; - + if (ConstantExpr::getOr(hasDestructor, hasCustomDelete) != ConstantInt::getFalse(A.M.getContext())) return false; - + Ty = MD_GetElement(node, CD_BodyType)->getType(); return true; } - + // The default promote() should be fine. - + AllocClassFI() : FunctionInfo(~0u, true) {} }; } @@ -252,27 +252,27 @@ namespace { class LLVM_LIBRARY_VISIBILITY GarbageCollect2Stack : public FunctionPass { StringMap KnownFunctions; Module* M; - + FunctionInfo AllocMemoryT; ArrayFI NewArrayVT; ArrayFI NewArrayT; AllocClassFI AllocClass; - + public: static char ID; // Pass identification GarbageCollect2Stack(); - + bool doInitialization(Module &M) { this->M = &M; return false; } - + bool runOnFunction(Function &F); - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); - + AU.addPreserved(); AU.addPreserved(); } @@ -285,7 +285,7 @@ X("dgc2stack", "Promote (GC'ed) heap allocations to stack"); // Public interface to the pass. FunctionPass *createGarbageCollect2Stack() { - return new GarbageCollect2Stack(); + return new GarbageCollect2Stack(); } GarbageCollect2Stack::GarbageCollect2Stack() @@ -305,7 +305,7 @@ static void RemoveCall(CallSite CS, const Analysis& A) { InvokeInst* Invoke = cast(CS.getInstruction()); // If this was an invoke instruction, we need to do some extra // work to preserve the control flow. - + // Create a "conditional" branch that -simplifycfg can clean up, so we // can keep using the DominatorTree without updating it. BranchInst::Create(Invoke->getNormalDest(), Invoke->getUnwindDest(), @@ -323,18 +323,18 @@ static bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT); /// bool GarbageCollect2Stack::runOnFunction(Function &F) { DEBUG(errs() << "\nRunning -dgc2stack on function " << F.getName() << '\n'); - + TargetData& TD = getAnalysis(); DominatorTree& DT = getAnalysis(); CallGraph* CG = getAnalysisIfAvailable(); CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL; - + Analysis A = { TD, *M, CG, CGNode }; - + BasicBlock& Entry = F.getEntryBlock(); - + IRBuilder<> AllocaBuilder(&Entry, Entry.begin()); - + bool Changed = false; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { @@ -343,53 +343,53 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) { CallSite CS = CallSite::get(Inst); if (!CS.getInstruction()) continue; - + // Ignore indirect calls and calls to non-external functions. Function *Callee = CS.getCalledFunction(); if (Callee == 0 || !Callee->isDeclaration() || !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage())) continue; - + // Ignore unknown calls. StringMap::iterator OMI = KnownFunctions.find(Callee->getName()); if (OMI == KnownFunctions.end()) continue; - + assert(isa(Inst->getType()) && "GC function doesn't return a pointer?"); - + FunctionInfo* info = OMI->getValue(); - + if (Inst->use_empty() && info->SafeToDelete) { Changed = true; NumDeleted++; RemoveCall(CS, A); continue; } - + DEBUG(errs() << "GarbageCollect2Stack inspecting: " << *Inst); - + if (!info->analyze(CS, A) || !isSafeToStackAllocate(Inst, DT)) continue; - + // Let's alloca this! Changed = true; - + IRBuilder<> Builder(BB, Inst); Value* newVal = info->promote(CS, Builder, A); - + DEBUG(errs() << "Promoted to: " << *newVal); - + // Make sure the type is the same as it was before, and replace all // uses of the runtime call with the alloca. if (newVal->getType() != Inst->getType()) newVal = Builder.CreateBitCast(newVal, Inst->getType()); Inst->replaceAllUsesWith(newVal); - + RemoveCall(CS, A); } } - + return Changed; } @@ -397,7 +397,7 @@ const Type* Analysis::getTypeFor(Value* typeinfo) const { GlobalVariable* ti_global = dyn_cast(typeinfo->stripPointerCasts()); if (!ti_global) return NULL; - + std::string metaname = TD_PREFIX; metaname += ti_global->getName(); @@ -414,7 +414,7 @@ const Type* Analysis::getTypeFor(Value* typeinfo) const { if (TD_Confirm >= 0 && (!MD_GetElement(node, TD_Confirm) || MD_GetElement(node, TD_Confirm)->stripPointerCasts() != ti_global)) return NULL; - + return MD_GetElement(node, TD_Type)->getType(); } @@ -422,7 +422,7 @@ const Type* Analysis::getTypeFor(Value* typeinfo) const { /// (without executing Def again). static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, DominatorTree& DT) { DEBUG(errs() << "### mayBeUsedAfterRealloc()\n" << *Def << *Alloc); - + // If the definition isn't used it obviously won't be used after the // allocation. // If it does not dominate the allocation, there's no way for it to be used @@ -432,12 +432,12 @@ static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, Dominato DEBUG(errs() << "### No uses or does not dominate allocation\n"); return false; } - + DEBUG(errs() << "### Def dominates Alloc\n"); - + BasicBlock* DefBlock = Def->getParent(); BasicBlock* AllocBlock = Alloc->getParent(); - + // Create a set of users and one of blocks containing users. SmallSet Users; SmallSet UserBlocks; @@ -446,7 +446,7 @@ static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, Dominato Instruction* User = cast(*UI); DEBUG(errs() << "USER: " << *User); BasicBlock* UserBlock = User->getParent(); - + // This dominance check is not performed if they're in the same block // because it will just walk the instruction list to figure it out. // We will instead do that ourselves in the first iteration (for all @@ -457,34 +457,34 @@ static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, Dominato DEBUG(errs() << "### Alloc dominates user " << *User); return true; } - + // Phi nodes are checked separately, so no need to enter them here. if (!isa(User)) { Users.insert(User); UserBlocks.insert(UserBlock); } } - + // Contains first instruction of block to inspect. typedef std::pair StartPoint; SmallVector Worklist; // Keeps track of successors that have been added to the work list. SmallSet Visited; - + // Start just after the allocation. // Note that we don't insert AllocBlock into the Visited set here so the // start of the block will get inspected if it's reachable. BasicBlock::iterator Start = Alloc; ++Start; Worklist.push_back(StartPoint(AllocBlock, Start)); - + while (!Worklist.empty()) { StartPoint sp = Worklist.pop_back_val(); BasicBlock* B = sp.first; BasicBlock::iterator BBI = sp.second; // BBI is either just after the allocation (in the first iteration) // or just after the last phi node in B (in subsequent iterations) here. - + // This whole 'if' is just a way to avoid performing the inner 'for' // loop when it can be determined not to be necessary, avoiding // potentially expensive walks of the instruction list. @@ -517,7 +517,7 @@ static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, Dominato // No users and no definition or allocation after the start point, // so just keep going. } - + // All instructions after the starting point in this block have been // accounted for. Look for successors to add to the work list. TerminatorInst* Term = B->getTerminator(); @@ -555,32 +555,32 @@ static bool mayBeUsedAfterRealloc(Instruction* Def, Instruction* Alloc, Dominato /// escape from the function and no derived pointers are live at the call site /// (i.e. if it's in a loop then the function can't use any pointer returned /// from an earlier call after a new call has been made) -/// +/// /// This is currently conservative where loops are involved: it can handle /// simple loops, but returns false if any derived pointer is used in a /// subsequent iteration. -/// +/// /// Based on LLVM's PointerMayBeCaptured(), which only does escape analysis but /// doesn't care about loops. bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) { assert(isa(Alloc->getType()) && "Allocation is not a pointer?"); Value* V = Alloc; - + SmallVector Worklist; SmallSet Visited; - + for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; ++UI) { Use *U = &UI.getUse(); Visited.insert(U); Worklist.push_back(U); } - + while (!Worklist.empty()) { Use *U = Worklist.pop_back_val(); Instruction *I = cast(U->getUser()); V = U->get(); - + switch (I->getOpcode()) { case Instruction::Call: case Instruction::Invoke: { @@ -591,7 +591,7 @@ bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) { if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType() == Type::getVoidTy(I->getContext())) break; - + // Not captured if only passed via 'nocapture' arguments. Note that // calling a function pointer does not in itself cause the pointer to // be captured. This is a subtle point considering that (for example) @@ -628,7 +628,7 @@ bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) { // the original allocation. if (mayBeUsedAfterRealloc(I, Alloc, DT)) return false; - + // The original value is not captured via this if the new value isn't. for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); UI != UE; ++UI) { @@ -642,7 +642,7 @@ bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) { return false; } } - + // All uses examined - not captured or live across original allocation. return true; } diff --git a/gen/structs.cpp b/gen/structs.cpp index 96adac017c..44ec0dd1e1 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -187,7 +187,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, const std::vector& inits, bool isConst) { - // get arrays + // get arrays size_t nvars = sd->fields.dim; VarDeclaration** vars = (VarDeclaration**)sd->fields.data; @@ -347,7 +347,7 @@ std::vector DtoStructLiteralValues(const StructDeclaration* sd, /// Union types will get expanded into a struct, with a type for each member. LLType* DtoUnpaddedStructType(Type* dty) { assert(dty->ty == Tstruct); - + typedef llvm::DenseMap CacheT; static llvm::ManagedStatic cache; CacheT::iterator it = cache->find(dty); @@ -383,9 +383,9 @@ LLValue* DtoUnpaddedStruct(Type* dty, LLValue* v) { assert(dty->ty == Tstruct); TypeStruct* sty = static_cast(dty); Array& fields = sty->sym->fields; - + LLValue* newval = llvm::UndefValue::get(DtoUnpaddedStructType(dty)); - + for (unsigned i = 0; i < fields.dim; i++) { VarDeclaration* vd = static_cast(fields.data[i]); LLValue* fieldptr = DtoIndexStruct(v, sty->sym, vd); @@ -406,7 +406,7 @@ void DtoPaddedStruct(Type* dty, LLValue* v, LLValue* lval) { assert(dty->ty == Tstruct); TypeStruct* sty = static_cast(dty); Array& fields = sty->sym->fields; - + for (unsigned i = 0; i < fields.dim; i++) { VarDeclaration* vd = static_cast(fields.data[i]); LLValue* fieldptr = DtoIndexStruct(lval, sty->sym, vd); diff --git a/ir/irfunction.cpp b/ir/irfunction.cpp index c103755fdc..ab0a834e01 100644 --- a/ir/irfunction.cpp +++ b/ir/irfunction.cpp @@ -158,7 +158,7 @@ IrFunction::IrFunction(FuncDeclaration* fd) frameType = NULL; depth = -1; nestedContextCreated = false; - + _arguments = NULL; _argptr = NULL; } diff --git a/ir/irfunction.h b/ir/irfunction.h index 74acb488be..e167f47a68 100644 --- a/ir/irfunction.h +++ b/ir/irfunction.h @@ -33,10 +33,10 @@ struct IRTargetScope { // generating statement Statement* s; - + // the try of a TryFinally that encloses the loop EnclosingHandler* enclosinghandler; - + llvm::BasicBlock* breakTarget; llvm::BasicBlock* continueTarget; @@ -84,7 +84,7 @@ struct IrFunction : IrBase { // constructor IrFunction(FuncDeclaration* fd); - + // annotations void setNeverInline(); void setAlwaysInline(); @@ -98,21 +98,21 @@ struct IrFunction : IrBase bool queued; bool defined; - + llvm::Value* retArg; // return in ptr arg llvm::Value* thisArg; // class/struct 'this' arg llvm::Value* nestArg; // nested function 'this' arg - + llvm::Value* nestedVar; // nested var alloca llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array) // number of enclosing functions with variables accessed by nested functions // (-1 if neither this function nor any enclosing ones access variables from enclosing functions) int depth; bool nestedContextCreated; // holds whether nested context is created - + llvm::Value* _arguments; llvm::Value* _argptr; - + llvm::DISubprogram diSubprogram; std::stack diLexicalBlocks; }; diff --git a/ir/irstruct.h b/ir/irstruct.h index cb0c6f325e..535f880771 100644 --- a/ir/irstruct.h +++ b/ir/irstruct.h @@ -42,7 +42,7 @@ struct IrStruct : IrBase /// Aggregate D type. Type* type; - /// true only for: align(1) struct S { ... } + /// true only for: align(1) struct S { ... } bool packed; /// Composite type debug description.