diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -106,6 +106,10 @@ ///< Set when -fxray-always-emit-typedevents is enabled. CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0) +///< Set when -fxray-ignore-loops is enabled. +CODEGENOPT(XRayIgnoreLoops , 1, 0) + + ///< Set the minimum number of instructions in a function to determine selective ///< XRay instrumentation. VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1292,6 +1292,13 @@ def fnoxray_always_emit_typedevents : Flag<["-"], "fno-xray-always-emit-typedevents">, Group, Flags<[CC1Option]>; +def fxray_ignore_loops : Flag<["-"], "fxray-ignore-loops">, Group, + Flags<[CC1Option]>, + HelpText<"Don't instrument functions with loops unless they also meet the minimum function size">; +def fno_xray_ignore_loops : Flag<["-"], "fno-xray-ignore-loops">, Group, + Flags<[CC1Option]>; + + def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group, Flags<[CC1Option]>, HelpText<"Tells clang to add the link dependencies for XRay.">; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -108,37 +108,45 @@ // Map the LangOption for rounding mode into // the corresponding enum in the IR. -static llvm::fp::RoundingMode ToConstrainedRoundingMD( - LangOptions::FPRoundingModeKind Kind) { +static llvm::fp::RoundingMode +ToConstrainedRoundingMD(LangOptions::FPRoundingModeKind Kind) { switch (Kind) { - case LangOptions::FPR_ToNearest: return llvm::fp::rmToNearest; - case LangOptions::FPR_Downward: return llvm::fp::rmDownward; - case LangOptions::FPR_Upward: return llvm::fp::rmUpward; - case LangOptions::FPR_TowardZero: return llvm::fp::rmTowardZero; - case LangOptions::FPR_Dynamic: return llvm::fp::rmDynamic; + case LangOptions::FPR_ToNearest: + return llvm::fp::rmToNearest; + case LangOptions::FPR_Downward: + return llvm::fp::rmDownward; + case LangOptions::FPR_Upward: + return llvm::fp::rmUpward; + case LangOptions::FPR_TowardZero: + return llvm::fp::rmTowardZero; + case LangOptions::FPR_Dynamic: + return llvm::fp::rmDynamic; } llvm_unreachable("Unsupported FP RoundingMode"); } // Map the LangOption for exception behavior into // the corresponding enum in the IR. -static llvm::fp::ExceptionBehavior ToConstrainedExceptMD( - LangOptions::FPExceptionModeKind Kind) { +static llvm::fp::ExceptionBehavior +ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) { switch (Kind) { - case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore; - case LangOptions::FPE_MayTrap: return llvm::fp::ebMayTrap; - case LangOptions::FPE_Strict: return llvm::fp::ebStrict; + case LangOptions::FPE_Ignore: + return llvm::fp::ebIgnore; + case LangOptions::FPE_MayTrap: + return llvm::fp::ebMayTrap; + case LangOptions::FPE_Strict: + return llvm::fp::ebStrict; } llvm_unreachable("Unsupported FP Exception Behavior"); } void CodeGenFunction::SetFPModel() { - auto fpRoundingMode = ToConstrainedRoundingMD( - getLangOpts().getFPRoundingMode()); - auto fpExceptionBehavior = ToConstrainedExceptMD( - getLangOpts().getFPExceptionMode()); + auto fpRoundingMode = + ToConstrainedRoundingMD(getLangOpts().getFPRoundingMode()); + auto fpExceptionBehavior = + ToConstrainedExceptMD(getLangOpts().getFPExceptionMode()); if (fpExceptionBehavior == llvm::fp::ebIgnore && fpRoundingMode == llvm::fp::rmToNearest) @@ -151,9 +159,8 @@ } } -CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo, - TBAAAccessInfo *TBAAInfo) { +CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment( + QualType T, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { return getNaturalTypeAlignment(T->getPointeeType(), BaseInfo, TBAAInfo, /* forPointeeType= */ true); } @@ -216,8 +223,8 @@ /// Given a value of type T* that may not be to a complete object, /// construct an l-value with the natural pointee alignment of T. -LValue -CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) { +LValue CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, + QualType T) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; CharUnits Align = getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, @@ -225,7 +232,6 @@ return MakeAddrLValue(Address(V, Align), T, BaseInfo, TBAAInfo); } - llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { return CGM.getTypes().ConvertTypeForMem(T); } @@ -312,7 +318,7 @@ // cleans up functions which started with a unified return block. if (ReturnBlock.getBlock()->hasOneUse()) { llvm::BranchInst *BI = - dyn_cast(*ReturnBlock.getBlock()->user_begin()); + dyn_cast(*ReturnBlock.getBlock()->user_begin()); if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock.getBlock()) { // Record/return the DebugLoc of the simple 'return' expression to be used @@ -335,7 +341,8 @@ } static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { - if (!BB) return; + if (!BB) + return; if (!BB->use_empty()) return CGF.CurFn->getBasicBlockList().push_back(BB); delete BB; @@ -345,9 +352,9 @@ assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); - bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0 - && NumSimpleReturnExprs == NumReturnExprs - && ReturnBlock.getBlock()->use_empty(); + bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0 && + NumSimpleReturnExprs == NumReturnExprs && + ReturnBlock.getBlock()->use_empty(); // Usually the return expression is evaluated before the cleanup // code. If the function contains only a simple return statement, // such as a constant, the location before the cleanup code becomes @@ -412,8 +419,7 @@ EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc, EndLoc); EmitEndEHSpec(CurCodeDecl); - assert(EHStack.empty() && - "did not remove all scopes from cleanup stack!"); + assert(EHStack.empty() && "did not remove all scopes from cleanup stack!"); // If someone did an indirect goto, emit the indirect goto block at the end of // the function. @@ -462,7 +468,7 @@ if (CGM.getCodeGenOpts().EmitDeclMetadata) EmitDeclMetadata(); - for (SmallVectorImpl >::iterator + for (SmallVectorImpl>::iterator I = DeferredReplacements.begin(), E = DeferredReplacements.end(); I != E; ++I) { @@ -486,8 +492,9 @@ // Scan function arguments for vector width. for (llvm::Argument &A : CurFn->args()) if (auto *VT = dyn_cast(A.getType())) - LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, - VT->getPrimitiveSizeInBits().getFixedSize()); + LargestVectorWidth = + std::max((uint64_t)LargestVectorWidth, + VT->getPrimitiveSizeInBits().getFixedSize()); // Update vector width based on return type. if (auto *VT = dyn_cast(CurFn->getReturnType())) @@ -589,8 +596,7 @@ } void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, - llvm::Function *Fn) -{ + llvm::Function *Fn) { if (!FD->hasAttr()) return; @@ -618,7 +624,8 @@ llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())), llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())), llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))}; - Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs)); + Fn->setMetadata("work_group_size_hint", + llvm::MDNode::get(Context, AttrMDArgs)); } if (const ReqdWorkGroupSizeAttr *A = FD->getAttr()) { @@ -626,7 +633,8 @@ llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())), llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())), llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))}; - Fn->setMetadata("reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs)); + Fn->setMetadata("reqd_work_group_size", + llvm::MDNode::get(Context, AttrMDArgs)); } if (const OpenCLIntelReqdSubGroupSizeAttr *A = @@ -639,7 +647,7 @@ } /// Determine whether the function F ends with a return stmt. -static bool endsWithReturn(const Decl* F) { +static bool endsWithReturn(const Decl *F) { const Stmt *Body = nullptr; if (auto *FD = dyn_cast_or_null(F)) Body = FD->getBody(); @@ -752,7 +760,8 @@ // Apply sanitizer attributes to the function. if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) Fn->addFnAttr(llvm::Attribute::SanitizeAddress); - if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress)) + if (SanOpts.hasOneOf(SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)) Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); if (SanOpts.has(SanitizerKind::MemTag)) Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); @@ -776,7 +785,8 @@ IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0); if (OMD->getMethodFamily() == OMF_dealloc || OMD->getMethodFamily() == OMF_initialize || - (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) { + (OMD->getSelector().isUnarySelector() && + II->isStr(".cxx_destruct"))) { markAsIgnoreThreadCheckingAtRuntime(Fn); } } @@ -818,15 +828,18 @@ Fn->addFnAttr( "xray-instruction-threshold", llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); + if (CGM.getCodeGenOpts().XRayIgnoreLoops) { + Fn->addFnAttr("xray-ignore-loops"); + } } if (const auto *Attr = D->getAttr()) { // Attr->getStart is currently ignored. Fn->addFnAttr("patchable-function-entry", std::to_string(Attr->getCount())); - } else if (unsigned Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount) { - Fn->addFnAttr("patchable-function-entry", - std::to_string(Count)); + } else if (unsigned Count = + CGM.getCodeGenOpts().PatchableFunctionEntryCount) { + Fn->addFnAttr("patchable-function-entry", std::to_string(Count)); } } @@ -858,9 +871,8 @@ if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) { // Remove any (C++17) exception specifications, to allow calling e.g. a // noexcept function through a non-noexcept pointer. - auto ProtoTy = - getContext().getFunctionTypeWithExceptionSpec(FD->getType(), - EST_None); + auto ProtoTy = getContext().getFunctionTypeWithExceptionSpec( + FD->getType(), EST_None); llvm::Constant *FTRTTIConst = CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); llvm::Constant *FTRTTIConstEncoded = @@ -970,14 +982,16 @@ if (CGM.getCodeGenOpts().MNopMCount) { if (!CGM.getCodeGenOpts().CallFEntry) CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) - << "-mnop-mcount" << "-mfentry"; + << "-mnop-mcount" + << "-mfentry"; Fn->addFnAttr("mnop-mcount"); } if (CGM.getCodeGenOpts().RecordMCount) { if (!CGM.getCodeGenOpts().CallFEntry) CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) - << "-mrecord-mcount" << "-mfentry"; + << "-mrecord-mcount" + << "-mfentry"; Fn->addFnAttr("mrecord-mcount"); } } @@ -987,7 +1001,7 @@ if (getContext().getTargetInfo().getTriple().getArch() != llvm::Triple::systemz) CGM.getDiags().Report(diag::err_opt_not_valid_on_target) - << "-mpacked-stack"; + << "-mpacked-stack"; Fn->addFnAttr("packed-stack"); } @@ -1028,8 +1042,7 @@ // Tell the epilog emitter to autorelease the result. We do this // now so that various specialized functions can suppress it // during their IR-generation. - if (getLangOpts().ObjCAutoRefCount && - !CurFnInfo->isReturnsRetained() && + if (getLangOpts().ObjCAutoRefCount && !CurFnInfo->isReturnsRetained() && RetTy->isObjCRetainableType()) AutoreleaseResult = true; } @@ -1047,8 +1060,7 @@ if (D && isa(D) && cast(D)->isInstance()) { CGM.getCXXABI().EmitInstanceFunctionProlog(*this); const CXXMethodDecl *MD = cast(D); - if (MD->getParent()->isLambda() && - MD->getOverloadedOperator() == OO_Call) { + if (MD->getParent()->isLambda() && MD->getOverloadedOperator() == OO_Call) { // We're in a lambda; figure out the captures. MD->getParent()->getCaptureFields(LambdaCaptureFields, LambdaThisCaptureField); @@ -1059,21 +1071,24 @@ // Get the lvalue for the field (which is a copy of the enclosing object // or contains the address of the enclosing object). - LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); + LValue ThisFieldLValue = + EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { - // If the enclosing object was captured by value, just use its address. + // If the enclosing object was captured by value, just use its + // address. CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); } else { // Load the lvalue pointed to by the field, since '*this' was captured // by reference. - CXXThisValue = - EmitLoadOfLValue(ThisFieldLValue, SourceLocation()).getScalarVal(); + CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation()) + .getScalarVal(); } } for (auto *FD : MD->getParent()->fields()) { if (FD->hasCapturedVLAType()) { - auto *ExprArg = EmitLoadOfLValue(EmitLValueForLambdaField(FD), - SourceLocation()).getScalarVal(); + auto *ExprArg = + EmitLoadOfLValue(EmitLValueForLambdaField(FD), SourceLocation()) + .getScalarVal(); auto VAT = FD->getCapturedVLAType(); VLASizeMap[VAT->getSizeExpr()] = ExprArg; } @@ -1108,8 +1123,8 @@ // If any of the arguments have a variably modified type, make sure to // emit the type size. - for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); - i != e; ++i) { + for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; + ++i) { const VarDecl *VD = *i; // Dig out the type as written from ParmVarDecls; it's unclear whether @@ -1171,7 +1186,8 @@ static void TryMarkNoThrow(llvm::Function *F) { // LLVM treats 'nounwind' on a function as part of the type, so we // can't do this on functions that can be overwritten. - if (F->isInterposable()) return; + if (F->isInterposable()) + return; for (llvm::BasicBlock &BB : *F) for (llvm::Instruction &I : BB) @@ -1287,8 +1303,7 @@ EmitDestructorBody(Args); else if (isa(FD)) EmitConstructorBody(Args); - else if (getLangOpts().CUDA && - !getLangOpts().CUDAIsDevice && + else if (getLangOpts().CUDA && !getLangOpts().CUDAIsDevice && FD->hasAttr()) CGM.getCUDARuntime().emitDeviceStub(*this, Args); else if (isa(FD) && @@ -1348,7 +1363,8 @@ /// that we can just remove the code. bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { // Null statement, not a label! - if (!S) return false; + if (!S) + return false; // If this is a label, we have to emit the code, consider something like: // if (0) { ... foo: bar(); } goto foo; @@ -1380,7 +1396,8 @@ /// inside of it, this is fine. bool CodeGenFunction::containsBreak(const Stmt *S) { // Null statement, not a label! - if (!S) return false; + if (!S) + return false; // If this is a switch or loop that defines its own break scope, then we can // include it and anything inside of it. @@ -1400,7 +1417,8 @@ } bool CodeGenFunction::mightAddDeclToScope(const Stmt *S) { - if (!S) return false; + if (!S) + return false; // Some statement kinds add a scope and thus never add a decl to the current // scope. Note, this list is longer than the list of statements that might @@ -1446,18 +1464,16 @@ // to bool. Expr::EvalResult Result; if (!Cond->EvaluateAsInt(Result, getContext())) - return false; // Not foldable, not integer or not fully evaluatable. + return false; // Not foldable, not integer or not fully evaluatable. llvm::APSInt Int = Result.Val.getInt(); if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond)) - return false; // Contains a label. + return false; // Contains a label. ResultInt = Int; return true; } - - /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if /// statement) to the specified blocks. Based on the condition, this might try /// to simplify the codegen of the conditional based on the branch. @@ -1625,7 +1641,7 @@ // br(c ? throw x : y, t, f) -> br(c, br(throw x, t, f), br(y, t, f) // Fold this to: // br(c, throw x, br(y, t, f)) - EmitCXXThrowExpr(Throw, /*KeepInsertionPoint*/false); + EmitCXXThrowExpr(Throw, /*KeepInsertionPoint*/ false); return; } @@ -1676,13 +1692,12 @@ CGBuilderTy &Builder = CGF.Builder; CharUnits baseSize = CGF.getContext().getTypeSizeInChars(baseType); - llvm::Value *baseSizeInChars - = llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity()); + llvm::Value *baseSizeInChars = + llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity()); - Address begin = - Builder.CreateElementBitCast(dest, CGF.Int8Ty, "vla.begin"); + Address begin = Builder.CreateElementBitCast(dest, CGF.Int8Ty, "vla.begin"); llvm::Value *end = - Builder.CreateInBoundsGEP(begin.getPointer(), sizeInChars, "vla.end"); + Builder.CreateInBoundsGEP(begin.getPointer(), sizeInChars, "vla.end"); llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); @@ -1695,8 +1710,7 @@ llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur"); cur->addIncoming(begin.getPointer(), originBB); - CharUnits curAlign = - dest.getAlignment().alignmentOfArrayElement(baseSize); + CharUnits curAlign = dest.getAlignment().alignmentOfArrayElement(baseSize); // memcpy the individual element bit-pattern. Builder.CreateMemCpy(Address(cur, curAlign), src, baseSizeInChars, @@ -1704,7 +1718,7 @@ // Go to the next element. llvm::Value *next = - Builder.CreateInBoundsGEP(CGF.Int8Ty, cur, baseSizeInChars, "vla.next"); + Builder.CreateInBoundsGEP(CGF.Int8Ty, cur, baseSizeInChars, "vla.next"); // Leave if that's the end of the VLA. llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone"); @@ -1714,8 +1728,7 @@ CGF.EmitBlock(contBB); } -void -CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) { +void CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) { // Ignore empty classes in C++. if (getLangOpts().CPlusPlus) { if (const RecordType *RT = Ty->getAs()) { @@ -1737,9 +1750,8 @@ // Don't bother emitting a zero-byte memset. if (size.isZero()) { // But note that getTypeInfo returns 0 for a VLA. - if (const VariableArrayType *vlaType = - dyn_cast_or_null( - getContext().getAsArrayType(Ty))) { + if (const VariableArrayType *vlaType = dyn_cast_or_null( + getContext().getAsArrayType(Ty))) { auto VlaSize = getVLASize(vlaType); SizeVal = VlaSize.NumElts; CharUnits eltSize = getContext().getTypeSizeInChars(VlaSize.Type); @@ -1760,21 +1772,22 @@ // like -1, which happens to be the pattern used by member-pointers. if (!CGM.getTypes().isZeroInitializable(Ty)) { // For a VLA, emit a single element, then splat that over the VLA. - if (vla) Ty = getContext().getBaseElementType(vla); + if (vla) + Ty = getContext().getBaseElementType(vla); llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty); - llvm::GlobalVariable *NullVariable = - new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(), - /*isConstant=*/true, - llvm::GlobalVariable::PrivateLinkage, - NullConstant, Twine()); + llvm::GlobalVariable *NullVariable = new llvm::GlobalVariable( + CGM.getModule(), NullConstant->getType(), + /*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, NullConstant, + Twine()); CharUnits NullAlign = DestPtr.getAlignment(); NullVariable->setAlignment(NullAlign.getAsAlign()); Address SrcPtr(Builder.CreateBitCast(NullVariable, Builder.getInt8PtrTy()), NullAlign); - if (vla) return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal); + if (vla) + return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal); // Get and call the appropriate llvm.memcpy overload. Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, false); @@ -1801,13 +1814,14 @@ llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() { // If we already made the indirect branch for indirect goto, return its block. - if (IndirectBranch) return IndirectBranch->getParent(); + if (IndirectBranch) + return IndirectBranch->getParent(); CGBuilderTy TmpBuilder(*this, createBasicBlock("indirectgoto")); // Create the PHI node that indirect gotos will add entries to. - llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, 0, - "indirect.goto.dest"); + llvm::Value *DestVal = + TmpBuilder.CreatePHI(Int8PtrTy, 0, "indirect.goto.dest"); // Create the indirect branch instruction. IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal); @@ -1847,7 +1861,7 @@ // We have some number of constant-length arrays, so addr should // have LLVM type [M x [N x [...]]]*. Build a GEP that walks // down to the first element of addr. - SmallVector gepIndices; + SmallVector gepIndices; // GEP down to the array type. llvm::ConstantInt *zero = Builder.getInt32(0); @@ -1857,18 +1871,17 @@ QualType eltType; llvm::ArrayType *llvmArrayType = - dyn_cast(addr.getElementType()); + dyn_cast(addr.getElementType()); while (llvmArrayType) { assert(isa(arrayType)); - assert(cast(arrayType)->getSize().getZExtValue() - == llvmArrayType->getNumElements()); + assert(cast(arrayType)->getSize().getZExtValue() == + llvmArrayType->getNumElements()); gepIndices.push_back(zero); countFromCLAs *= llvmArrayType->getNumElements(); eltType = arrayType->getElementType(); - llvmArrayType = - dyn_cast(llvmArrayType->getElementType()); + llvmArrayType = dyn_cast(llvmArrayType->getElementType()); arrayType = getContext().getAsArrayType(arrayType->getElementType()); assert((!llvmArrayType || arrayType) && "LLVM and Clang types are out-of-synch"); @@ -1889,15 +1902,14 @@ addr = Builder.CreateElementBitCast(addr, baseType, "array.begin"); } else { // Create the actual GEP. - addr = Address(Builder.CreateInBoundsGEP(addr.getPointer(), - gepIndices, "array.begin"), - addr.getAlignment()); + addr = Address( + Builder.CreateInBoundsGEP(addr.getPointer(), gepIndices, "array.begin"), + addr.getAlignment()); } baseType = eltType; - llvm::Value *numElements - = llvm::ConstantInt::get(SizeTy, countFromCLAs); + llvm::Value *numElements = llvm::ConstantInt::get(SizeTy, countFromCLAs); // If we had any VLA dimensions, factor them in. if (numVLAElements) @@ -1933,11 +1945,10 @@ } } while ((type = getContext().getAsVariableArrayType(elementType))); - return { numElements, elementType }; + return {numElements, elementType}; } -CodeGenFunction::VlaSizePair -CodeGenFunction::getVLAElements1D(QualType type) { +CodeGenFunction::VlaSizePair CodeGenFunction::getVLAElements1D(QualType type) { const VariableArrayType *vla = getContext().getAsVariableArrayType(type); assert(vla && "type was not a variable array type!"); return getVLAElements1D(vla); @@ -1948,7 +1959,7 @@ llvm::Value *VlaSize = VLASizeMap[Vla->getSizeExpr()]; assert(VlaSize && "no size for VLA!"); assert(VlaSize->getType() == SizeTy); - return { VlaSize, Vla->getElementType() }; + return {VlaSize, Vla->getElementType()}; } void CodeGenFunction::EmitVariablyModifiedType(QualType type) { @@ -2096,7 +2107,7 @@ } while (type->isVariablyModifiedType()); } -Address CodeGenFunction::EmitVAListRef(const Expr* E) { +Address CodeGenFunction::EmitVAListRef(const Expr *E) { if (getContext().getBuiltinVaListType()->isArrayType()) return EmitPointerWithAlignment(E); return EmitLValue(E).getAddress(*this); @@ -2120,9 +2131,11 @@ // is trunc(zext) folding, but if we add more, we can easily // extend this protection. - if (!rvalue.isScalar()) return PeepholeProtection(); + if (!rvalue.isScalar()) + return PeepholeProtection(); llvm::Value *value = rvalue.getScalarVal(); - if (!isa(value)) return PeepholeProtection(); + if (!isa(value)) + return PeepholeProtection(); // Just make an extra bitcast. assert(HaveInsertPoint()); @@ -2135,7 +2148,8 @@ } void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) { - if (!protection.Inst) return; + if (!protection.Inst) + return; // In theory, we could try to duplicate the peepholes now, but whatever. protection.Inst->eraseFromParent(); @@ -2174,11 +2188,10 @@ StringRef AnnotationStr, SourceLocation Location) { llvm::Value *Args[4] = { - AnnotatedVal, - Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy), - Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy), - CGM.EmitAnnotationLineNo(Location) - }; + AnnotatedVal, + Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy), + Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy), + CGM.EmitAnnotationLineNo(Location)}; return Builder.CreateCall(AnnotationFn, Args); } @@ -2197,8 +2210,8 @@ assert(D->hasAttr() && "no annotate attribute"); llvm::Value *V = Addr.getPointer(); llvm::Type *VTy = V->getType(); - llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, - CGM.Int8PtrTy); + llvm::Function *F = + CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, CGM.Int8PtrTy); for (const auto *I : D->specific_attrs()) { // FIXME Always emit the cast inst so we can differentiate between @@ -2213,7 +2226,7 @@ return Address(V, Addr.getAlignment()); } -CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { } +CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() {} CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF) : CGF(CGF) { @@ -2256,18 +2269,18 @@ // If we have at least one of the features in the feature list return // true, otherwise return false. - return std::all_of( - ReqFeatures.begin(), ReqFeatures.end(), [&](StringRef Feature) { - SmallVector OrFeatures; - Feature.split(OrFeatures, '|'); - return llvm::any_of(OrFeatures, [&](StringRef Feature) { - if (!CallerFeatureMap.lookup(Feature)) { - FirstMissing = Feature.str(); - return false; - } - return true; - }); - }); + return std::all_of(ReqFeatures.begin(), ReqFeatures.end(), + [&](StringRef Feature) { + SmallVector OrFeatures; + Feature.split(OrFeatures, '|'); + return llvm::any_of(OrFeatures, [&](StringRef Feature) { + if (!CallerFeatureMap.lookup(Feature)) { + FirstMissing = Feature.str(); + return false; + } + return true; + }); + }); } // Emits an error if we don't have a valid set of target features for the diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1091,6 +1091,8 @@ Args.hasArg(OPT_fxray_always_emit_typedevents); Opts.XRayInstructionThreshold = getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags); + Opts.XRayIgnoreLoops = + Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false); auto XRayInstrBundles = Args.getAllArgValues(OPT_fxray_instrumentation_bundle); diff --git a/clang/test/CodeGen/xray-ignore-loops.cpp b/clang/test/CodeGen/xray-ignore-loops.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/xray-ignore-loops.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s + +int foo() { + return 1; +} + +// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] { +// CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}