diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/BackendConsumer.h | 34 | ||||
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 20 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGHLSLRuntime.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 67 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 28 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 16 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 44 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.cpp | 19 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.h | 17 | ||||
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.cpp | 220 | ||||
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.h | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/SanitizerMetadata.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/Targets/NVPTX.cpp | 39 | ||||
-rw-r--r-- | clang/lib/CodeGen/Targets/SPIR.cpp | 37 |
21 files changed, 380 insertions, 238 deletions
diff --git a/clang/lib/CodeGen/BackendConsumer.h b/clang/lib/CodeGen/BackendConsumer.h index a023d29..d932a78 100644 --- a/clang/lib/CodeGen/BackendConsumer.h +++ b/clang/lib/CodeGen/BackendConsumer.h @@ -29,17 +29,16 @@ class BackendConsumer : public ASTConsumer { virtual void anchor(); DiagnosticsEngine &Diags; - BackendAction Action; const HeaderSearchOptions &HeaderSearchOpts; const CodeGenOptions &CodeGenOpts; const TargetOptions &TargetOpts; const LangOptions &LangOpts; std::unique_ptr<raw_pwrite_stream> AsmOutStream; - ASTContext *Context; + ASTContext *Context = nullptr; IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; llvm::Timer LLVMIRGeneration; - unsigned LLVMIRGenerationRefCount; + unsigned LLVMIRGenerationRefCount = 0; /// True if we've finished generating IR. This prevents us from generating /// additional LLVM IR after emitting output in HandleTranslationUnit. This @@ -48,6 +47,8 @@ class BackendConsumer : public ASTConsumer { bool TimerIsEnabled = false; + BackendAction Action; + std::unique_ptr<CodeGenerator> Gen; SmallVector<LinkModule, 4> LinkModules; @@ -69,29 +70,12 @@ class BackendConsumer : public ASTConsumer { llvm::Module *CurLinkModule = nullptr; public: - BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, - const HeaderSearchOptions &HeaderSearchOpts, - const PreprocessorOptions &PPOpts, - const CodeGenOptions &CodeGenOpts, - const TargetOptions &TargetOpts, const LangOptions &LangOpts, - const std::string &InFile, - SmallVector<LinkModule, 4> LinkModules, - std::unique_ptr<raw_pwrite_stream> OS, llvm::LLVMContext &C, - CoverageSourceInfo *CoverageInfo = nullptr); - - // This constructor is used in installing an empty BackendConsumer - // to use the clang diagnostic handler for IR input files. It avoids - // initializing the OS field. - BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, + BackendConsumer(const CompilerInstance &CI, BackendAction Action, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, - const HeaderSearchOptions &HeaderSearchOpts, - const PreprocessorOptions &PPOpts, - const CodeGenOptions &CodeGenOpts, - const TargetOptions &TargetOpts, const LangOptions &LangOpts, - llvm::Module *Module, SmallVector<LinkModule, 4> LinkModules, - llvm::LLVMContext &C, - CoverageSourceInfo *CoverageInfo = nullptr); + llvm::LLVMContext &C, SmallVector<LinkModule, 4> LinkModules, + StringRef InFile, std::unique_ptr<raw_pwrite_stream> OS, + CoverageSourceInfo *CoverageInfo, + llvm::Module *CurLinkModule = nullptr); llvm::Module *getModule() const; std::unique_ptr<llvm::Module> takeModule(); diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 04358cd..2dbab78 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -736,10 +736,8 @@ static void addSanitizers(const Triple &TargetTriple, MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); } - if (LangOpts.Sanitize.has(SanitizerKind::Type)) { - MPM.addPass(ModuleTypeSanitizerPass()); - MPM.addPass(createModuleToFunctionPassAdaptor(TypeSanitizerPass())); - } + if (LangOpts.Sanitize.has(SanitizerKind::Type)) + MPM.addPass(TypeSanitizerPass()); if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability)) MPM.addPass(NumericalStabilitySanitizerPass()); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 5cd893d..573be93 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -11327,6 +11327,19 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, if (Builtin->LLVMIntrinsic == 0) return nullptr; + if (BuiltinID == SME::BI__builtin_sme___arm_in_streaming_mode) { + // If we already know the streaming mode, don't bother with the intrinsic + // and emit a constant instead + const auto *FD = cast<FunctionDecl>(CurFuncDecl); + if (const auto *FPT = FD->getType()->getAs<FunctionProtoType>()) { + unsigned SMEAttrs = FPT->getAArch64SMEAttributes(); + if (!(SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)) { + bool IsStreaming = SMEAttrs & FunctionType::SME_PStateSMEnabledMask; + return ConstantInt::getBool(Builder.getContext(), IsStreaming); + } + } + } + // Predicates must match the main datatype. for (unsigned i = 0, e = Ops.size(); i != e; ++i) if (auto PredTy = dyn_cast<llvm::VectorType>(Ops[i]->getType())) @@ -19199,8 +19212,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, // TODO: Map to an hlsl_device address space. llvm::Type *RetTy = llvm::PointerType::getUnqual(getLLVMContext()); - return Builder.CreateIntrinsic(RetTy, Intrinsic::dx_resource_getpointer, - ArrayRef<Value *>{HandleOp, IndexOp}); + return Builder.CreateIntrinsic( + RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(), + ArrayRef<Value *>{HandleOp, IndexOp}); } case Builtin::BI__builtin_hlsl_all: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 89e2eac..7b0ef4b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -6090,6 +6090,8 @@ RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr, VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr()) : EmitVAListRef(VE->getSubExpr()); QualType Ty = VE->getType(); + if (Ty->isVariablyModifiedType()) + EmitVariablyModifiedType(Ty); if (VE->isMicrosoftABI()) return CGM.getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty, Slot); return CGM.getABIInfo().EmitVAArg(*this, VAListAddr, Ty, Slot); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 47b21bc..6f3ff05 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -361,6 +361,8 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, return GV; } + PGO.markStmtMaybeUsed(D.getInit()); // FIXME: Too lazy + #ifndef NDEBUG CharUnits VarSize = CGM.getContext().getTypeSizeInChars(D.getType()) + D.getFlexibleArrayInitChars(getContext()); @@ -1868,7 +1870,10 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { // If we are at an unreachable point, we don't need to emit the initializer // unless it contains a label. if (!HaveInsertPoint()) { - if (!Init || !ContainsLabel(Init)) return; + if (!Init || !ContainsLabel(Init)) { + PGO.markStmtMaybeUsed(Init); + return; + } EnsureInsertPoint(); } @@ -1979,6 +1984,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { return EmitExprAsInit(Init, &D, lv, capturedByInit); } + PGO.markStmtMaybeUsed(Init); + if (!emission.IsConstantAggregate) { // For simple scalar/complex initialization, store the value directly. LValue lv = MakeAddrLValue(Loc, type); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index ba1cba29..1bad7a7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5148,6 +5148,7 @@ std::optional<LValue> HandleConditionalOperatorLValueSimpleCase( // If the true case is live, we need to track its region. if (CondExprBool) CGF.incrementProfileCounter(E); + CGF.markStmtMaybeUsed(Dead); // If a throw expression we emit it and return an undefined lvalue // because it can't be used. if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Live->IgnoreParens())) { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 4b71bd7..0f27bd0 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -5003,7 +5003,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { CGF.incrementProfileCounter(E->getRHS()); CGF.EmitBranch(FBlock); CGF.EmitBlock(FBlock); - } + } else + CGF.markStmtMaybeUsed(E->getRHS()); CGF.MCDCLogOpStack.pop_back(); // If the top of the logical operator nest, update the MCDC bitmap. @@ -5015,8 +5016,10 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { } // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. - if (!CGF.ContainsLabel(E->getRHS())) + if (!CGF.ContainsLabel(E->getRHS())) { + CGF.markStmtMaybeUsed(E->getRHS()); return llvm::Constant::getNullValue(ResTy); + } } // If the top of the logical operator nest, reset the MCDC temp to 0. @@ -5143,7 +5146,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { CGF.incrementProfileCounter(E->getRHS()); CGF.EmitBranch(FBlock); CGF.EmitBlock(FBlock); - } + } else + CGF.markStmtMaybeUsed(E->getRHS()); CGF.MCDCLogOpStack.pop_back(); // If the top of the logical operator nest, update the MCDC bitmap. @@ -5155,8 +5159,10 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { } // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. - if (!CGF.ContainsLabel(E->getRHS())) + if (!CGF.ContainsLabel(E->getRHS())) { + CGF.markStmtMaybeUsed(E->getRHS()); return llvm::ConstantInt::get(ResTy, 1); + } } // If the top of the logical operator nest, reset the MCDC temp to 0. @@ -5280,6 +5286,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { CGF.incrementProfileCounter(E); } Value *Result = Visit(live); + CGF.markStmtMaybeUsed(dead); // If the live part is a throw expression, it acts like it has a void // type, so evaluating it returns a null Value*. However, a conditional @@ -5448,11 +5455,6 @@ Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) { } Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { - QualType Ty = VE->getType(); - - if (Ty->isVariablyModifiedType()) - CGF.EmitVariablyModifiedType(Ty); - Address ArgValue = Address::invalid(); RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 3d57241..46e472f 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -104,6 +104,8 @@ public: GENERATE_HLSL_INTRINSIC_FUNCTION(SClamp, sclamp) GENERATE_HLSL_INTRINSIC_FUNCTION(UClamp, uclamp) + GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointer, + resource_getpointer) GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, resource_handlefrombinding) GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 85be2b4..e9a8500 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -76,6 +76,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { // Verify that any decl statements were handled as simple, they may be in // scope of subsequent reachable statements. assert(!isa<DeclStmt>(*S) && "Unexpected DeclStmt!"); + PGO.markStmtMaybeUsed(S); return; } @@ -482,6 +483,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { case Stmt::OpenACCSetConstructClass: EmitOpenACCSetConstruct(cast<OpenACCSetConstruct>(*S)); break; + case Stmt::OpenACCUpdateConstructClass: + EmitOpenACCUpdateConstruct(cast<OpenACCUpdateConstruct>(*S)); + break; } } @@ -754,8 +758,6 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { bool noinline = false; bool alwaysinline = false; bool noconvergent = false; - HLSLControlFlowHintAttr::Spelling flattenOrBranch = - HLSLControlFlowHintAttr::SpellingNotCalculated; const CallExpr *musttail = nullptr; for (const auto *A : S.getAttrs()) { @@ -787,9 +789,6 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { Builder.CreateAssumption(AssumptionVal); } } break; - case attr::HLSLControlFlowHint: { - flattenOrBranch = cast<HLSLControlFlowHintAttr>(A)->getSemanticSpelling(); - } break; } } SaveAndRestore save_nomerge(InNoMergeAttributedStmt, nomerge); @@ -797,7 +796,6 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { SaveAndRestore save_alwaysinline(InAlwaysInlineAttributedStmt, alwaysinline); SaveAndRestore save_noconvergent(InNoConvergentAttributedStmt, noconvergent); SaveAndRestore save_musttail(MustTailCall, musttail); - SaveAndRestore save_flattenOrBranch(HLSLControlFlowAttr, flattenOrBranch); EmitStmt(S.getSubStmt(), S.getAttrs()); } @@ -878,6 +876,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { RunCleanupsScope ExecutedScope(*this); EmitStmt(Executed); } + PGO.markStmtMaybeUsed(Skipped); return; } } @@ -2200,6 +2199,7 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) EmitStmt(CaseStmts[i]); incrementProfileCounter(&S); + PGO.markStmtMaybeUsed(S.getBody()); // Now we want to restore the saved switch instance so that nested // switches continue to function properly diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index cc927f4..f63cb9b 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -106,46 +106,19 @@ static void reportOptRecordError(Error E, DiagnosticsEngine &Diags, } BackendConsumer::BackendConsumer( - BackendAction Action, DiagnosticsEngine &Diags, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, - const HeaderSearchOptions &HeaderSearchOpts, - const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, - const TargetOptions &TargetOpts, const LangOptions &LangOpts, - const std::string &InFile, SmallVector<LinkModule, 4> LinkModules, - std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C, - CoverageSourceInfo *CoverageInfo) - : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), - CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), - AsmOutStream(std::move(OS)), Context(nullptr), FS(VFS), - LLVMIRGeneration("irgen", "LLVM IR Generation Time"), - LLVMIRGenerationRefCount(0), - Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS), HeaderSearchOpts, - PPOpts, CodeGenOpts, C, CoverageInfo)), - LinkModules(std::move(LinkModules)) { - TimerIsEnabled = CodeGenOpts.TimePasses; - llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; - llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun; -} - -// This constructor is used in installing an empty BackendConsumer -// to use the clang diagnostic handler for IR input files. It avoids -// initializing the OS field. -BackendConsumer::BackendConsumer( - BackendAction Action, DiagnosticsEngine &Diags, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, - const HeaderSearchOptions &HeaderSearchOpts, - const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, - const TargetOptions &TargetOpts, const LangOptions &LangOpts, - llvm::Module *Module, SmallVector<LinkModule, 4> LinkModules, - LLVMContext &C, CoverageSourceInfo *CoverageInfo) - : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), - CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), - Context(nullptr), FS(VFS), - LLVMIRGeneration("irgen", "LLVM IR Generation Time"), - LLVMIRGenerationRefCount(0), - Gen(CreateLLVMCodeGen(Diags, "", std::move(VFS), HeaderSearchOpts, PPOpts, - CodeGenOpts, C, CoverageInfo)), - LinkModules(std::move(LinkModules)), CurLinkModule(Module) { + const CompilerInstance &CI, BackendAction Action, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, LLVMContext &C, + SmallVector<LinkModule, 4> LinkModules, StringRef InFile, + std::unique_ptr<raw_pwrite_stream> OS, CoverageSourceInfo *CoverageInfo, + llvm::Module *CurLinkModule) + : Diags(CI.getDiagnostics()), HeaderSearchOpts(CI.getHeaderSearchOpts()), + CodeGenOpts(CI.getCodeGenOpts()), TargetOpts(CI.getTargetOpts()), + LangOpts(CI.getLangOpts()), AsmOutStream(std::move(OS)), FS(VFS), + LLVMIRGeneration("irgen", "LLVM IR Generation Time"), Action(Action), + Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS), + CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), + CI.getCodeGenOpts(), C, CoverageInfo)), + LinkModules(std::move(LinkModules)), CurLinkModule(CurLinkModule) { TimerIsEnabled = CodeGenOpts.TimePasses; llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun; @@ -1011,10 +984,8 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CI.getPreprocessor()); std::unique_ptr<BackendConsumer> Result(new BackendConsumer( - BA, CI.getDiagnostics(), &CI.getVirtualFileSystem(), - CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(), - CI.getTargetOpts(), CI.getLangOpts(), std::string(InFile), - std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo)); + CI, BA, &CI.getVirtualFileSystem(), *VMContext, std::move(LinkModules), + InFile, std::move(OS), CoverageInfo)); BEConsumer = Result.get(); // Enable generating macro debug info only when debug info is not disabled and @@ -1182,11 +1153,9 @@ void CodeGenAction::ExecuteAction() { // Set clang diagnostic handler. To do this we need to create a fake // BackendConsumer. - BackendConsumer Result(BA, CI.getDiagnostics(), &CI.getVirtualFileSystem(), - CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), - CI.getCodeGenOpts(), CI.getTargetOpts(), - CI.getLangOpts(), TheModule.get(), - std::move(LinkModules), *VMContext, nullptr); + BackendConsumer Result(CI, BA, &CI.getVirtualFileSystem(), *VMContext, + std::move(LinkModules), "", nullptr, nullptr, + TheModule.get()); // Link in each pending link module. if (!CodeGenOpts.LinkBitcodePostopt && Result.LinkInModules(&*TheModule)) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 067ff55..27ec68b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -40,7 +40,6 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/FPEnv.h" -#include "llvm/IR/Instruction.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" @@ -1617,6 +1616,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // Emit the standard function epilogue. FinishFunction(BodyRange.getEnd()); + PGO.verifyCounterMap(); + // If we haven't marked the function nothrow through other means, do // a quick pass now to see if we can. if (!CurFn->doesNotThrow()) @@ -1739,6 +1740,7 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond)) return false; // Contains a label. + PGO.markStmtMaybeUsed(Cond); ResultInt = Int; return true; } @@ -2084,29 +2086,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr( Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount); } - llvm::Instruction *BrInst = Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, - Weights, Unpredictable); - switch (HLSLControlFlowAttr) { - case HLSLControlFlowHintAttr::Microsoft_branch: - case HLSLControlFlowHintAttr::Microsoft_flatten: { - llvm::MDBuilder MDHelper(CGM.getLLVMContext()); - - llvm::ConstantInt *BranchHintConstant = - HLSLControlFlowAttr == - HLSLControlFlowHintAttr::Spelling::Microsoft_branch - ? llvm::ConstantInt::get(CGM.Int32Ty, 1) - : llvm::ConstantInt::get(CGM.Int32Ty, 2); - - SmallVector<llvm::Metadata *, 2> Vals( - {MDHelper.createString("hlsl.controlflow.hint"), - MDHelper.createConstant(BranchHintConstant)}); - BrInst->setMetadata("hlsl.controlflow.hint", - llvm::MDNode::get(CGM.getLLVMContext(), Vals)); - break; - } - case HLSLControlFlowHintAttr::SpellingNotCalculated: - break; - } + Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable); } /// ErrorUnsupported - Print out an error that codegen doesn't support the diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 0cd03c9..e2dc0b1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -615,10 +615,6 @@ public: /// True if the current statement has noconvergent attribute. bool InNoConvergentAttributedStmt = false; - /// HLSL Branch attribute. - HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr = - HLSLControlFlowHintAttr::SpellingNotCalculated; - // The CallExpr within the current statement that the musttail attribute // applies to. nullptr if there is no 'musttail' on the current statement. const CallExpr *MustTailCall = nullptr; @@ -1624,6 +1620,13 @@ private: uint64_t LoopCount) const; public: + auto getIsCounterPair(const Stmt *S) const { return PGO.getIsCounterPair(S); } + + void markStmtAsUsed(bool Skipped, const Stmt *S) { + PGO.markStmtAsUsed(Skipped, S); + } + void markStmtMaybeUsed(const Stmt *S) { PGO.markStmtMaybeUsed(S); } + /// Increment the profiler's counter for the given statement by \p StepV. /// If \p StepV is null, the default increment is 1. void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { @@ -4142,6 +4145,11 @@ public: // but in the future we will implement some sort of IR. } + void EmitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // but in the future we will implement some sort of IR. + } + //===--------------------------------------------------------------------===// // LValue Expression Emission //===--------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c49f763..7db1ed7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2748,7 +2748,21 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, Attrs.addAttribute("target-features", llvm::join(Features, ",")); AddedAttr = true; } - + if (getTarget().getTriple().isAArch64()) { + llvm::SmallVector<StringRef, 8> Feats; + if (TV) + TV->getFeatures(Feats); + else if (TC) + TC->getFeatures(Feats, GD.getMultiVersionIndex()); + if (!Feats.empty()) { + llvm::sort(Feats); + std::string FMVFeatures; + for (StringRef F : Feats) + FMVFeatures.append(",+" + F.str()); + Attrs.addAttribute("fmv-features", FMVFeatures.substr(1)); + AddedAttr = true; + } + } return AddedAttr; } @@ -4227,7 +4241,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, llvm::Function *NewFn); -static unsigned getFMVPriority(const TargetInfo &TI, +static uint64_t getFMVPriority(const TargetInfo &TI, const CodeGenFunction::FMVResolverOption &RO) { llvm::SmallVector<StringRef, 8> Features{RO.Features}; if (RO.Architecture) diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 741b0f1..d5ef1a7 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -102,6 +102,50 @@ enum ForDefinition_t : bool { ForDefinition = true }; +/// The Counter with an optional additional Counter for +/// branches. `Skipped` counter can be calculated with `Executed` and +/// a common Counter (like `Parent`) as `(Parent-Executed)`. +/// +/// In SingleByte mode, Counters are binary. Subtraction is not +/// applicable (but addition is capable). In this case, both +/// `Executed` and `Skipped` counters are required. `Skipped` is +/// `None` by default. It is allocated in the coverage mapping. +/// +/// There might be cases that `Parent` could be induced with +/// `(Executed+Skipped)`. This is not always applicable. +class CounterPair { +public: + /// Optional value. + class ValueOpt { + private: + static constexpr uint32_t None = (1u << 31); /// None is allocated. + static constexpr uint32_t Mask = None - 1; + + uint32_t Val; + + public: + ValueOpt() : Val(None) {} + + ValueOpt(unsigned InitVal) { + assert(!(InitVal & ~Mask)); + Val = InitVal; + } + + bool hasValue() const { return !(Val & None); } + + operator uint32_t() const { return Val; } + }; + + ValueOpt Executed; + ValueOpt Skipped; /// May be None. + + /// Initialized with Skipped=None. + CounterPair(unsigned Val) : Executed(Val) {} + + // FIXME: Should work with {None, None} + CounterPair() : Executed(0) {} +}; + struct OrderGlobalInitsOrStermFinalizers { unsigned int priority; unsigned int lex_order; diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 17d7902..7923738 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -163,7 +163,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { /// The function hash. PGOHash Hash; /// The map of statements to counters. - llvm::DenseMap<const Stmt *, unsigned> &CounterMap; + llvm::DenseMap<const Stmt *, CounterPair> &CounterMap; /// The state of MC/DC Coverage in this function. MCDC::State &MCDCState; /// Maximum number of supported MC/DC conditions in a boolean expression. @@ -174,7 +174,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { DiagnosticsEngine &Diag; MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion, - llvm::DenseMap<const Stmt *, unsigned> &CounterMap, + llvm::DenseMap<const Stmt *, CounterPair> &CounterMap, MCDC::State &MCDCState, unsigned MCDCMaxCond, DiagnosticsEngine &Diag) : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap), @@ -1083,7 +1083,7 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) { (CGM.getCodeGenOpts().MCDCCoverage ? CGM.getCodeGenOpts().MCDCMaxConds : 0); - RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>); + RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, CounterPair>); RegionMCDCState.reset(new MCDC::State); MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap, *RegionMCDCState, MCDCMaxConditions, CGM.getDiags()); @@ -1185,12 +1185,23 @@ CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, Fn->setEntryCount(FunctionCount); } +std::pair<bool, bool> CodeGenPGO::getIsCounterPair(const Stmt *S) const { + if (!RegionCounterMap) + return {false, false}; + + auto I = RegionCounterMap->find(S); + if (I == RegionCounterMap->end()) + return {false, false}; + + return {I->second.Executed.hasValue(), I->second.Skipped.hasValue()}; +} + void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV) { if (!RegionCounterMap || !Builder.GetInsertBlock()) return; - unsigned Counter = (*RegionCounterMap)[S]; + unsigned Counter = (*RegionCounterMap)[S].Executed; // Make sure that pointer to global is passed in with zero addrspace // This is relevant during GPU profiling diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 9d66ffa..1944b64 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -35,7 +35,7 @@ private: std::array <unsigned, llvm::IPVK_Last + 1> NumValueSites; unsigned NumRegionCounters; uint64_t FunctionHash; - std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionCounterMap; + std::unique_ptr<llvm::DenseMap<const Stmt *, CounterPair>> RegionCounterMap; std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap; std::unique_ptr<llvm::InstrProfRecord> ProfRecord; std::unique_ptr<MCDC::State> RegionMCDCState; @@ -110,6 +110,7 @@ private: bool canEmitMCDCCoverage(const CGBuilderTy &Builder); public: + std::pair<bool, bool> getIsCounterPair(const Stmt *S) const; void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV); void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, @@ -122,6 +123,18 @@ public: Address MCDCCondBitmapAddr, llvm::Value *Val, CodeGenFunction &CGF); + void markStmtAsUsed(bool Skipped, const Stmt *S) { + // Do nothing. + } + + void markStmtMaybeUsed(const Stmt *S) { + // Do nothing. + } + + void verifyCounterMap() const { + // Do nothing. + } + /// Return the region count for the counter at the given index. uint64_t getRegionCount(const Stmt *S) { if (!RegionCounterMap) @@ -130,7 +143,7 @@ public: return 0; // With profiles from a differing version of clang we can have mismatched // decl counts. Don't crash in such a case. - auto Index = (*RegionCounterMap)[S]; + auto Index = (*RegionCounterMap)[S].Executed; if (Index >= RegionCounts.size()) return 0; return RegionCounts[Index]; diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index cda218e..f091577 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -882,7 +882,7 @@ struct CounterCoverageMappingBuilder : public CoverageMappingBuilder, public ConstStmtVisitor<CounterCoverageMappingBuilder> { /// The map of statements to count values. - llvm::DenseMap<const Stmt *, unsigned> &CounterMap; + llvm::DenseMap<const Stmt *, CounterPair> &CounterMap; MCDC::State &MCDCState; @@ -919,15 +919,11 @@ struct CounterCoverageMappingBuilder /// Return a counter for the sum of \c LHS and \c RHS. Counter addCounters(Counter LHS, Counter RHS, bool Simplify = true) { - assert(!llvm::EnableSingleByteCoverage && - "cannot add counters when single byte coverage mode is enabled"); return Builder.add(LHS, RHS, Simplify); } Counter addCounters(Counter C1, Counter C2, Counter C3, bool Simplify = true) { - assert(!llvm::EnableSingleByteCoverage && - "cannot add counters when single byte coverage mode is enabled"); return addCounters(addCounters(C1, C2, Simplify), C3, Simplify); } @@ -935,7 +931,51 @@ struct CounterCoverageMappingBuilder /// /// This should only be called on statements that have a dedicated counter. Counter getRegionCounter(const Stmt *S) { - return Counter::getCounter(CounterMap[S]); + return Counter::getCounter(CounterMap[S].Executed); + } + + struct BranchCounterPair { + Counter Executed; ///< The Counter previously assigned. + Counter Skipped; ///< An expression (Parent-Executed), or equivalent to it. + }; + + /// Retrieve or assign the pair of Counter(s). + /// + /// This returns BranchCounterPair {Executed, Skipped}. + /// Executed is the Counter associated with S assigned by an earlier + /// CounterMapping pass. + /// Skipped may be an expression (Executed - ParentCnt) or newly + /// assigned Counter in EnableSingleByteCoverage, as subtract + /// expressions are not available in this mode. + /// + /// \param S Key to the CounterMap + /// \param ParentCnt The Counter representing how many times S is evaluated. + /// \param SkipCntForOld (To be removed later) Optional fake Counter + /// to override Skipped for adjustment of + /// expressions in the old behavior of + /// EnableSingleByteCoverage that is unaware of + /// Branch coverage. + BranchCounterPair + getBranchCounterPair(const Stmt *S, Counter ParentCnt, + std::optional<Counter> SkipCntForOld = std::nullopt) { + Counter ExecCnt = getRegionCounter(S); + + // The old behavior of SingleByte is unaware of Branches. + // Will be pruned after the migration of SingleByte. + if (llvm::EnableSingleByteCoverage) { + assert(SkipCntForOld && + "SingleByte must provide SkipCntForOld as a fake Skipped count."); + return {ExecCnt, *SkipCntForOld}; + } + + return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; + } + + bool IsCounterEqual(Counter OutCount, Counter ParentCount) { + if (OutCount == ParentCount) + return true; + + return false; } /// Push a region onto the stack. @@ -1417,7 +1457,7 @@ struct CounterCoverageMappingBuilder CounterCoverageMappingBuilder( CoverageMappingModuleGen &CVM, - llvm::DenseMap<const Stmt *, unsigned> &CounterMap, + llvm::DenseMap<const Stmt *, CounterPair> &CounterMap, MCDC::State &MCDCState, SourceManager &SM, const LangOptions &LangOpts) : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap), MCDCState(MCDCState), MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {} @@ -1588,6 +1628,10 @@ struct CounterCoverageMappingBuilder llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(ParentCount, BackedgeCount, BC.ContinueCount); + auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); + propagateCounts(CondCount, S->getCond()); adjustForOutOfOrderTraversal(getEnd(S)); @@ -1596,13 +1640,11 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, - subtractCounters(CondCount, BodyCount)); - - if (OutCount != ParentCount) { + assert( + !llvm::EnableSingleByteCoverage || + (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S))); + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; if (BodyHasTerminateStmt) @@ -1611,8 +1653,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(CondCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); } void VisitDoStmt(const DoStmt *S) { @@ -1641,22 +1682,24 @@ struct CounterCoverageMappingBuilder Counter CondCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(BackedgeCount, BC.ContinueCount); + auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); + propagateCounts(CondCount, S->getCond()); - Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, - subtractCounters(CondCount, BodyCount)); - if (OutCount != ParentCount) { + assert( + !llvm::EnableSingleByteCoverage || + (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S))); + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(CondCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); if (BodyHasTerminateStmt) HasTerminateStmt = true; @@ -1705,6 +1748,9 @@ struct CounterCoverageMappingBuilder : addCounters( addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), IncrementBC.ContinueCount); + auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); if (const Expr *Cond = S->getCond()) { propagateCounts(CondCount, Cond); @@ -1716,12 +1762,11 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, - subtractCounters(CondCount, BodyCount)); - if (OutCount != ParentCount) { + assert(!llvm::EnableSingleByteCoverage || + (BodyBC.BreakCount.isZero() && IncrementBC.BreakCount.isZero())); + Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, + BranchCount.Skipped); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; if (BodyHasTerminateStmt) @@ -1730,8 +1775,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(CondCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); } void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { @@ -1759,16 +1803,17 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount; - Counter LoopCount; - if (llvm::EnableSingleByteCoverage) - OutCount = getRegionCounter(S); - else { - LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - OutCount = - addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); - } - if (OutCount != ParentCount) { + Counter LoopCount = + addCounters(ParentCount, BackedgeCount, BC.ContinueCount); + auto BranchCount = getBranchCounterPair(S, LoopCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); + assert( + !llvm::EnableSingleByteCoverage || + (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S))); + + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; if (BodyHasTerminateStmt) @@ -1777,8 +1822,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(LoopCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); } void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { @@ -1800,9 +1844,10 @@ struct CounterCoverageMappingBuilder Counter LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - Counter OutCount = - addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); - if (OutCount != ParentCount) { + auto BranchCount = getBranchCounterPair(S, LoopCount); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount); + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } @@ -2010,9 +2055,12 @@ struct CounterCoverageMappingBuilder extendRegion(S->getCond()); Counter ParentCount = getRegion().getCounter(); - Counter ThenCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getThen()) - : getRegionCounter(S); + auto [ThenCount, ElseCount] = + (llvm::EnableSingleByteCoverage + ? BranchCounterPair{getRegionCounter(S->getThen()), + (S->getElse() ? getRegionCounter(S->getElse()) + : Counter::getZero())} + : getBranchCounterPair(S, ParentCount)); // Emitting a counter for the condition makes it easier to interpret the // counter for the body when looking at the coverage. @@ -2027,12 +2075,6 @@ struct CounterCoverageMappingBuilder extendRegion(S->getThen()); Counter OutCount = propagateCounts(ThenCount, S->getThen()); - Counter ElseCount; - if (!llvm::EnableSingleByteCoverage) - ElseCount = subtractCounters(ParentCount, ThenCount); - else if (S->getElse()) - ElseCount = getRegionCounter(S->getElse()); - if (const Stmt *Else = S->getElse()) { bool ThenHasTerminateStmt = HasTerminateStmt; HasTerminateStmt = false; @@ -2055,15 +2097,14 @@ struct CounterCoverageMappingBuilder if (llvm::EnableSingleByteCoverage) OutCount = getRegionCounter(S); - if (OutCount != ParentCount) { + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } if (!llvm::EnableSingleByteCoverage) // Create Branch Region around condition. - createBranchRegion(S->getCond(), ThenCount, - subtractCounters(ParentCount, ThenCount)); + createBranchRegion(S->getCond(), ThenCount, ElseCount); } void VisitCXXTryStmt(const CXXTryStmt *S) { @@ -2089,9 +2130,11 @@ struct CounterCoverageMappingBuilder extendRegion(E); Counter ParentCount = getRegion().getCounter(); - Counter TrueCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(E->getTrueExpr()) - : getRegionCounter(E); + auto [TrueCount, FalseCount] = + (llvm::EnableSingleByteCoverage + ? BranchCounterPair{getRegionCounter(E->getTrueExpr()), + getRegionCounter(E->getFalseExpr())} + : getBranchCounterPair(E, ParentCount)); Counter OutCount; if (const auto *BCO = dyn_cast<BinaryConditionalOperator>(E)) { @@ -2110,25 +2153,20 @@ struct CounterCoverageMappingBuilder } extendRegion(E->getFalseExpr()); - Counter FalseCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(E->getFalseExpr()) - : subtractCounters(ParentCount, TrueCount); - Counter FalseOutCount = propagateCounts(FalseCount, E->getFalseExpr()); if (llvm::EnableSingleByteCoverage) OutCount = getRegionCounter(E); else OutCount = addCounters(OutCount, FalseOutCount); - if (OutCount != ParentCount) { + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getCond(), TrueCount, - subtractCounters(ParentCount, TrueCount)); + createBranchRegion(E->getCond(), TrueCount, FalseCount); } void createOrCancelDecision(const BinaryOperator *E, unsigned Since) { @@ -2227,27 +2265,27 @@ struct CounterCoverageMappingBuilder extendRegion(E->getRHS()); propagateCounts(getRegionCounter(E), E->getRHS()); + if (llvm::EnableSingleByteCoverage) + return; + // Track RHS True/False Decision. const auto DecisionRHS = MCDCBuilder.back(); + // Extract the Parent Region Counter. + Counter ParentCnt = getRegion().getCounter(); + // Extract the RHS's Execution Counter. - Counter RHSExecCnt = getRegionCounter(E); + auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt); // Extract the RHS's "True" Instance Counter. - Counter RHSTrueCnt = getRegionCounter(E->getRHS()); - - // Extract the Parent Region Counter. - Counter ParentCnt = getRegion().getCounter(); + auto [RHSTrueCnt, RHSExitCnt] = + getBranchCounterPair(E->getRHS(), RHSExecCnt); // Create Branch Region around LHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getLHS(), RHSExecCnt, - subtractCounters(ParentCnt, RHSExecCnt), DecisionLHS); + createBranchRegion(E->getLHS(), RHSExecCnt, LHSExitCnt, DecisionLHS); // Create Branch Region around RHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getRHS(), RHSTrueCnt, - subtractCounters(RHSExecCnt, RHSTrueCnt), DecisionRHS); + createBranchRegion(E->getRHS(), RHSTrueCnt, RHSExitCnt, DecisionRHS); // Create MCDC Decision Region if at top-level (root). if (IsRootNode) @@ -2288,31 +2326,31 @@ struct CounterCoverageMappingBuilder extendRegion(E->getRHS()); propagateCounts(getRegionCounter(E), E->getRHS()); + if (llvm::EnableSingleByteCoverage) + return; + // Track RHS True/False Decision. const auto DecisionRHS = MCDCBuilder.back(); + // Extract the Parent Region Counter. + Counter ParentCnt = getRegion().getCounter(); + // Extract the RHS's Execution Counter. - Counter RHSExecCnt = getRegionCounter(E); + auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt); // Extract the RHS's "False" Instance Counter. - Counter RHSFalseCnt = getRegionCounter(E->getRHS()); + auto [RHSFalseCnt, RHSExitCnt] = + getBranchCounterPair(E->getRHS(), RHSExecCnt); if (!shouldVisitRHS(E->getLHS())) { GapRegionCounter = OutCount; } - // Extract the Parent Region Counter. - Counter ParentCnt = getRegion().getCounter(); - // Create Branch Region around LHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt), - RHSExecCnt, DecisionLHS); + createBranchRegion(E->getLHS(), LHSExitCnt, RHSExecCnt, DecisionLHS); // Create Branch Region around RHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt), - RHSFalseCnt, DecisionRHS); + createBranchRegion(E->getRHS(), RHSExitCnt, RHSFalseCnt, DecisionRHS); // Create MCDC Decision Region if at top-level (root). if (IsRootNode) diff --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h index fe4b93f..0ed5059 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.h +++ b/clang/lib/CodeGen/CoverageMappingGen.h @@ -95,6 +95,7 @@ public: namespace CodeGen { class CodeGenModule; +class CounterPair; namespace MCDC { struct State; @@ -158,7 +159,7 @@ class CoverageMappingGen { CoverageMappingModuleGen &CVM; SourceManager &SM; const LangOptions &LangOpts; - llvm::DenseMap<const Stmt *, unsigned> *CounterMap; + llvm::DenseMap<const Stmt *, CounterPair> *CounterMap; MCDC::State *MCDCState; public: @@ -169,7 +170,7 @@ public: CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM, const LangOptions &LangOpts, - llvm::DenseMap<const Stmt *, unsigned> *CounterMap, + llvm::DenseMap<const Stmt *, CounterPair> *CounterMap, MCDC::State *MCDCState) : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap), MCDCState(MCDCState) {} diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 61fdf33..b7b212b 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -145,7 +145,9 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D, for (auto *Attr : D.specific_attrs<NoSanitizeAttr>()) NoSanitizeMask |= Attr->getMask(); - if (D.hasExternalStorage()) + // External definitions and incomplete types get handled at the place they + // are defined. + if (D.hasExternalStorage() || D.getType()->isIncompleteType()) NoSanitizeMask |= SanitizerKind::Type; return NoSanitizeMask; diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp index 0431d2c..b82e4dd 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -9,6 +9,7 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/CallingConv.h" #include "llvm/IR/IntrinsicsNVPTX.h" using namespace clang; @@ -79,13 +80,11 @@ public: // Adds a NamedMDNode with GV, Name, and Operand as operands, and adds the // resulting MDNode to the nvvm.annotations MDNode. static void addNVVMMetadata(llvm::GlobalValue *GV, StringRef Name, - int Operand, - const SmallVectorImpl<int> &GridConstantArgs); + int Operand); - static void addNVVMMetadata(llvm::GlobalValue *GV, StringRef Name, - int Operand) { - addNVVMMetadata(GV, Name, Operand, SmallVector<int, 1>(0)); - } + static void + addGridConstantNVVMMetadata(llvm::GlobalValue *GV, + const SmallVectorImpl<int> &GridConstantArgs); private: static void emitBuiltinSurfTexDeviceCopy(CodeGenFunction &CGF, LValue Dst, @@ -259,7 +258,7 @@ void NVPTXTargetCodeGenInfo::setTargetAttributes( if (FD->hasAttr<OpenCLKernelAttr>()) { // OpenCL __kernel functions get kernel metadata // Create !{<func-ref>, metadata !"kernel", i32 1} node - addNVVMMetadata(F, "kernel", 1); + F->setCallingConv(llvm::CallingConv::PTX_Kernel); // And kernel functions are not subject to inlining F->addFnAttr(llvm::Attribute::NoInline); } @@ -277,7 +276,8 @@ void NVPTXTargetCodeGenInfo::setTargetAttributes( // For some reason arg indices are 1-based in NVVM GCI.push_back(IV.index() + 1); // Create !{<func-ref>, metadata !"kernel", i32 1} node - addNVVMMetadata(F, "kernel", 1, GCI); + F->setCallingConv(llvm::CallingConv::PTX_Kernel); + addGridConstantNVVMMetadata(F, GCI); } if (CUDALaunchBoundsAttr *Attr = FD->getAttr<CUDALaunchBoundsAttr>()) M.handleCUDALaunchBoundsAttr(F, Attr); @@ -285,13 +285,12 @@ void NVPTXTargetCodeGenInfo::setTargetAttributes( // Attach kernel metadata directly if compiling for NVPTX. if (FD->hasAttr<NVPTXKernelAttr>()) { - addNVVMMetadata(F, "kernel", 1); + F->setCallingConv(llvm::CallingConv::PTX_Kernel); } } -void NVPTXTargetCodeGenInfo::addNVVMMetadata( - llvm::GlobalValue *GV, StringRef Name, int Operand, - const SmallVectorImpl<int> &GridConstantArgs) { +void NVPTXTargetCodeGenInfo::addNVVMMetadata(llvm::GlobalValue *GV, + StringRef Name, int Operand) { llvm::Module *M = GV->getParent(); llvm::LLVMContext &Ctx = M->getContext(); @@ -302,6 +301,21 @@ void NVPTXTargetCodeGenInfo::addNVVMMetadata( llvm::ConstantAsMetadata::get(GV), llvm::MDString::get(Ctx, Name), llvm::ConstantAsMetadata::get( llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), Operand))}; + + // Append metadata to nvvm.annotations + MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); +} + +void NVPTXTargetCodeGenInfo::addGridConstantNVVMMetadata( + llvm::GlobalValue *GV, const SmallVectorImpl<int> &GridConstantArgs) { + + llvm::Module *M = GV->getParent(); + llvm::LLVMContext &Ctx = M->getContext(); + + // Get "nvvm.annotations" metadata node + llvm::NamedMDNode *MD = M->getOrInsertNamedMetadata("nvvm.annotations"); + + SmallVector<llvm::Metadata *, 5> MDVals = {llvm::ConstantAsMetadata::get(GV)}; if (!GridConstantArgs.empty()) { SmallVector<llvm::Metadata *, 10> GCM; for (int I : GridConstantArgs) @@ -310,6 +324,7 @@ void NVPTXTargetCodeGenInfo::addNVVMMetadata( MDVals.append({llvm::MDString::get(Ctx, "grid_constant"), llvm::MDNode::get(Ctx, GCM)}); } + // Append metadata to nvvm.annotations MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); } diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index a48fe9d..5c75e98 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -64,6 +64,8 @@ public: void setCUDAKernelCallingConvention(const FunctionType *&FT) const override; LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const override; + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts, SyncScope Scope, llvm::AtomicOrdering Ordering, @@ -245,6 +247,41 @@ SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, return DefaultGlobalAS; } +void SPIRVTargetCodeGenInfo::setTargetAttributes( + const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { + if (!M.getLangOpts().HIP || + M.getTarget().getTriple().getVendor() != llvm::Triple::AMD) + return; + if (GV->isDeclaration()) + return; + + auto F = dyn_cast<llvm::Function>(GV); + if (!F) + return; + + auto FD = dyn_cast_or_null<FunctionDecl>(D); + if (!FD) + return; + if (!FD->hasAttr<CUDAGlobalAttr>()) + return; + + unsigned N = M.getLangOpts().GPUMaxThreadsPerBlock; + if (auto FlatWGS = FD->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) + N = FlatWGS->getMax()->EvaluateKnownConstInt(M.getContext()).getExtValue(); + + // We encode the maximum flat WG size in the first component of the 3D + // max_work_group_size attribute, which will get reverse translated into the + // original AMDGPU attribute when targeting AMDGPU. + auto Int32Ty = llvm::IntegerType::getInt32Ty(M.getLLVMContext()); + llvm::Metadata *AttrMDArgs[] = { + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, N)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 1)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 1))}; + + F->setMetadata("max_work_group_size", + llvm::MDNode::get(M.getLLVMContext(), AttrMDArgs)); +} + llvm::SyncScope::ID SPIRVTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &, SyncScope Scope, llvm::AtomicOrdering, |