[PATCH] D31405: [CodeGen] Pass SDAG an ORE, and replace FastISel stats with remarks.
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 29 22:50:38 PDT 2017
Ahmed Bougacha via Phabricator <reviews at reviews.llvm.org> writes:
> ab updated this revision to Diff 93385.
> ab edited the summary of this revision.
> ab added a comment.
>
> - Remove -fast-isel-verbose
> - Move ORE make_unique up
LGTM.
> https://reviews.llvm.org/D31405
>
> Files:
> include/llvm/CodeGen/SelectionDAG.h
> include/llvm/CodeGen/SelectionDAGISel.h
> lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> test/CodeGen/AArch64/fast-isel-tail-call.ll
> test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll
> test/CodeGen/Mips/Fast-ISel/fastcc-miss.ll
> test/CodeGen/X86/fast-isel-x86-64.ll
> test/CodeGen/X86/fast-isel-x86.ll
>
> Index: test/CodeGen/X86/fast-isel-x86.ll
> ===================================================================
> --- test/CodeGen/X86/fast-isel-x86.ll
> +++ test/CodeGen/X86/fast-isel-x86.ll
> @@ -1,5 +1,5 @@
> ; RUN: llc -fast-isel -O0 -mcpu=generic -mtriple=i386-apple-darwin10 -relocation-model=pic < %s | FileCheck %s
> -; RUN: llc -fast-isel -O0 -mcpu=generic -mtriple=i386-apple-darwin10 -relocation-model=pic < %s -fast-isel-verbose 2>&1 >/dev/null | FileCheck -check-prefix=STDERR -allow-empty %s
> +; RUN: llc -fast-isel -O0 -mcpu=generic -mtriple=i386-apple-darwin10 -relocation-model=pic < %s -pass-remarks-missed=isel 2>&1 >/dev/null | FileCheck -check-prefix=STDERR -allow-empty %s
>
> ; This should use flds to set the return value.
> ; CHECK-LABEL: test0:
> Index: test/CodeGen/X86/fast-isel-x86-64.ll
> ===================================================================
> --- test/CodeGen/X86/fast-isel-x86-64.ll
> +++ test/CodeGen/X86/fast-isel-x86-64.ll
> @@ -1,5 +1,5 @@
> ; RUN: llc < %s -mattr=-avx -fast-isel -mcpu=core2 -O0 -regalloc=fast -asm-verbose=0 -fast-isel-abort=1 | FileCheck %s
> -; RUN: llc < %s -mattr=-avx -fast-isel -mcpu=core2 -O0 -regalloc=fast -asm-verbose=0 -fast-isel-verbose 2>&1 >/dev/null | FileCheck %s --check-prefix=STDERR --allow-empty
> +; RUN: llc < %s -mattr=-avx -fast-isel -mcpu=core2 -O0 -regalloc=fast -asm-verbose=0 -pass-remarks-missed=isel 2>&1 >/dev/null | FileCheck %s --check-prefix=STDERR --allow-empty
> ; RUN: llc < %s -mattr=+avx -fast-isel -mcpu=core2 -O0 -regalloc=fast -asm-verbose=0 -fast-isel-abort=1 | FileCheck %s --check-prefix=AVX
>
> target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
> Index: test/CodeGen/Mips/Fast-ISel/fastcc-miss.ll
> ===================================================================
> --- test/CodeGen/Mips/Fast-ISel/fastcc-miss.ll
> +++ test/CodeGen/Mips/Fast-ISel/fastcc-miss.ll
> @@ -1,5 +1,5 @@
> ; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel 2>&1 | FileCheck %s
>
> ; CHECK: FastISel missed call:
> ; CHECK-SAME: %call = call fastcc i32 @foo(i32 signext %a, i32 signext %b)
> Index: test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll
> ===================================================================
> --- test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll
> +++ test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll
> @@ -1,40 +1,40 @@
> ; Targets where we should not enable FastISel.
> ; RUN: llc -march=mips -mcpu=mips2 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips3 -O0 -relocation-model=pic -target-abi n64 \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips4 -O0 -relocation-model=pic -target-abi n64 \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
>
> ; RUN: llc -march=mips -mcpu=mips32r6 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
>
> ; RUN: llc -march=mips -mattr=mips16 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
>
> ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+micromips -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips32r5 -mattr=+micromips -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
>
> ; RUN: llc -march=mips -mcpu=mips64 -O0 -relocation-model=pic -target-abi n64 \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips64r2 -O0 -relocation-model=pic -target-abi n64 \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips64r3 -O0 -relocation-model=pic -target-abi n64 \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips64r5 -O0 -relocation-model=pic -target-abi n64 \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
> ; RUN: llc -march=mips -mcpu=mips32r6 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s
>
> ; Valid targets for FastISel.
> ; RUN: llc -march=mips -mcpu=mips32r0 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s -check-prefix=FISEL
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s -check-prefix=FISEL
> ; RUN: llc -march=mips -mcpu=mips32r2 -O0 -relocation-model=pic \
> -; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s -check-prefix=FISEL
> +; RUN: -pass-remarks-missed=isel <%s 2>&1 | FileCheck %s -check-prefix=FISEL
>
> ; The CHECK prefix is being used by those targets that do not support FastISel.
> ; By checking that we don't emit the "FastISel missed terminator..." message,
> Index: test/CodeGen/AArch64/fast-isel-tail-call.ll
> ===================================================================
> --- test/CodeGen/AArch64/fast-isel-tail-call.ll
> +++ test/CodeGen/AArch64/fast-isel-tail-call.ll
> @@ -1,4 +1,5 @@
> -; RUN: llc -fast-isel -fast-isel-verbose -mtriple arm64-- < %s 2> %t | FileCheck %s
> +; RUN: llc -fast-isel -pass-remarks-missed=isel -pass-remarks-missed=isel \
> +; RUN: -mtriple arm64-- < %s 2> %t | FileCheck %s
> ; RUN: cat %t | FileCheck %s --check-prefix MISSED
>
> %struct = type { [4 x i32] }
> @@ -10,7 +11,7 @@
>
> ; Here, the %struct extractvalue should fail FastISel.
>
> -; MISSED: FastISel miss: %tmp1 = extractvalue %struct %tmp0, 0
> +; MISSED: FastISel missed: %tmp1 = extractvalue %struct %tmp0, 0
>
> ; CHECK-LABEL: test:
> ; CHECK: b external
> Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> @@ -26,6 +26,7 @@
> #include "llvm/Analysis/AliasAnalysis.h"
> #include "llvm/Analysis/BranchProbabilityInfo.h"
> #include "llvm/Analysis/CFG.h"
> +#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
> #include "llvm/Analysis/TargetLibraryInfo.h"
> #include "llvm/CodeGen/FastISel.h"
> #include "llvm/CodeGen/FunctionLoweringInfo.h"
> @@ -104,104 +105,6 @@
> STATISTIC(NumFastIselFailLowerArguments,
> "Number of entry blocks where fast isel failed to lower arguments");
>
> -#ifndef NDEBUG
> -static cl::opt<bool>
> -EnableFastISelVerbose2("fast-isel-verbose2", cl::Hidden,
> - cl::desc("Enable extra verbose messages in the \"fast\" "
> - "instruction selector"));
> -
> - // Terminators
> -STATISTIC(NumFastIselFailRet,"Fast isel fails on Ret");
> -STATISTIC(NumFastIselFailBr,"Fast isel fails on Br");
> -STATISTIC(NumFastIselFailSwitch,"Fast isel fails on Switch");
> -STATISTIC(NumFastIselFailIndirectBr,"Fast isel fails on IndirectBr");
> -STATISTIC(NumFastIselFailInvoke,"Fast isel fails on Invoke");
> -STATISTIC(NumFastIselFailResume,"Fast isel fails on Resume");
> -STATISTIC(NumFastIselFailUnreachable,"Fast isel fails on Unreachable");
> -
> - // Standard binary operators...
> -STATISTIC(NumFastIselFailAdd,"Fast isel fails on Add");
> -STATISTIC(NumFastIselFailFAdd,"Fast isel fails on FAdd");
> -STATISTIC(NumFastIselFailSub,"Fast isel fails on Sub");
> -STATISTIC(NumFastIselFailFSub,"Fast isel fails on FSub");
> -STATISTIC(NumFastIselFailMul,"Fast isel fails on Mul");
> -STATISTIC(NumFastIselFailFMul,"Fast isel fails on FMul");
> -STATISTIC(NumFastIselFailUDiv,"Fast isel fails on UDiv");
> -STATISTIC(NumFastIselFailSDiv,"Fast isel fails on SDiv");
> -STATISTIC(NumFastIselFailFDiv,"Fast isel fails on FDiv");
> -STATISTIC(NumFastIselFailURem,"Fast isel fails on URem");
> -STATISTIC(NumFastIselFailSRem,"Fast isel fails on SRem");
> -STATISTIC(NumFastIselFailFRem,"Fast isel fails on FRem");
> -
> - // Logical operators...
> -STATISTIC(NumFastIselFailAnd,"Fast isel fails on And");
> -STATISTIC(NumFastIselFailOr,"Fast isel fails on Or");
> -STATISTIC(NumFastIselFailXor,"Fast isel fails on Xor");
> -
> - // Memory instructions...
> -STATISTIC(NumFastIselFailAlloca,"Fast isel fails on Alloca");
> -STATISTIC(NumFastIselFailLoad,"Fast isel fails on Load");
> -STATISTIC(NumFastIselFailStore,"Fast isel fails on Store");
> -STATISTIC(NumFastIselFailAtomicCmpXchg,"Fast isel fails on AtomicCmpXchg");
> -STATISTIC(NumFastIselFailAtomicRMW,"Fast isel fails on AtomicRWM");
> -STATISTIC(NumFastIselFailFence,"Fast isel fails on Frence");
> -STATISTIC(NumFastIselFailGetElementPtr,"Fast isel fails on GetElementPtr");
> -
> - // Convert instructions...
> -STATISTIC(NumFastIselFailTrunc,"Fast isel fails on Trunc");
> -STATISTIC(NumFastIselFailZExt,"Fast isel fails on ZExt");
> -STATISTIC(NumFastIselFailSExt,"Fast isel fails on SExt");
> -STATISTIC(NumFastIselFailFPTrunc,"Fast isel fails on FPTrunc");
> -STATISTIC(NumFastIselFailFPExt,"Fast isel fails on FPExt");
> -STATISTIC(NumFastIselFailFPToUI,"Fast isel fails on FPToUI");
> -STATISTIC(NumFastIselFailFPToSI,"Fast isel fails on FPToSI");
> -STATISTIC(NumFastIselFailUIToFP,"Fast isel fails on UIToFP");
> -STATISTIC(NumFastIselFailSIToFP,"Fast isel fails on SIToFP");
> -STATISTIC(NumFastIselFailIntToPtr,"Fast isel fails on IntToPtr");
> -STATISTIC(NumFastIselFailPtrToInt,"Fast isel fails on PtrToInt");
> -STATISTIC(NumFastIselFailBitCast,"Fast isel fails on BitCast");
> -
> - // Other instructions...
> -STATISTIC(NumFastIselFailICmp,"Fast isel fails on ICmp");
> -STATISTIC(NumFastIselFailFCmp,"Fast isel fails on FCmp");
> -STATISTIC(NumFastIselFailPHI,"Fast isel fails on PHI");
> -STATISTIC(NumFastIselFailSelect,"Fast isel fails on Select");
> -STATISTIC(NumFastIselFailCall,"Fast isel fails on Call");
> -STATISTIC(NumFastIselFailShl,"Fast isel fails on Shl");
> -STATISTIC(NumFastIselFailLShr,"Fast isel fails on LShr");
> -STATISTIC(NumFastIselFailAShr,"Fast isel fails on AShr");
> -STATISTIC(NumFastIselFailVAArg,"Fast isel fails on VAArg");
> -STATISTIC(NumFastIselFailExtractElement,"Fast isel fails on ExtractElement");
> -STATISTIC(NumFastIselFailInsertElement,"Fast isel fails on InsertElement");
> -STATISTIC(NumFastIselFailShuffleVector,"Fast isel fails on ShuffleVector");
> -STATISTIC(NumFastIselFailExtractValue,"Fast isel fails on ExtractValue");
> -STATISTIC(NumFastIselFailInsertValue,"Fast isel fails on InsertValue");
> -STATISTIC(NumFastIselFailLandingPad,"Fast isel fails on LandingPad");
> -
> -// Intrinsic instructions...
> -STATISTIC(NumFastIselFailIntrinsicCall, "Fast isel fails on Intrinsic call");
> -STATISTIC(NumFastIselFailSAddWithOverflow,
> - "Fast isel fails on sadd.with.overflow");
> -STATISTIC(NumFastIselFailUAddWithOverflow,
> - "Fast isel fails on uadd.with.overflow");
> -STATISTIC(NumFastIselFailSSubWithOverflow,
> - "Fast isel fails on ssub.with.overflow");
> -STATISTIC(NumFastIselFailUSubWithOverflow,
> - "Fast isel fails on usub.with.overflow");
> -STATISTIC(NumFastIselFailSMulWithOverflow,
> - "Fast isel fails on smul.with.overflow");
> -STATISTIC(NumFastIselFailUMulWithOverflow,
> - "Fast isel fails on umul.with.overflow");
> -STATISTIC(NumFastIselFailFrameaddress, "Fast isel fails on Frameaddress");
> -STATISTIC(NumFastIselFailSqrt, "Fast isel fails on sqrt call");
> -STATISTIC(NumFastIselFailStackMap, "Fast isel fails on StackMap call");
> -STATISTIC(NumFastIselFailPatchPoint, "Fast isel fails on PatchPoint call");
> -#endif
> -
> -static cl::opt<bool>
> -EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
> - cl::desc("Enable verbose messages in the \"fast\" "
> - "instruction selector"));
> static cl::opt<int> EnableFastISelAbort(
> "fast-isel-abort", cl::Hidden,
> cl::desc("Enable abort calls when \"fast\" instruction selection "
> @@ -469,8 +372,6 @@
> MachineFunctionProperties::Property::Selected))
> return false;
> // Do some sanity-checking on the command-line options.
> - assert((!EnableFastISelVerbose || TM.Options.EnableFastISel) &&
> - "-fast-isel-verbose requires -fast-isel");
> assert((!EnableFastISelAbort || TM.Options.EnableFastISel) &&
> "-fast-isel-abort > 0 requires -fast-isel");
>
> @@ -495,12 +396,13 @@
> AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
> LibInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
> GFI = Fn.hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) : nullptr;
> + ORE = make_unique<OptimizationRemarkEmitter>(&Fn);
>
> DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
>
> SplitCriticalSideEffectEdges(const_cast<Function &>(Fn));
>
> - CurDAG->init(*MF);
> + CurDAG->init(*MF, *ORE);
> FuncInfo->set(Fn, *MF, CurDAG);
>
> if (UseMBPI && OptLevel != CodeGenOpt::None)
> @@ -708,6 +610,21 @@
> return true;
> }
>
> +static void reportFastISelFailure(MachineFunction &MF,
> + OptimizationRemarkEmitter &ORE,
> + OptimizationRemarkMissed &R,
> + bool ShouldAbort) {
> + // Print the function name explicitly if we don't have a debug location (which
> + // makes the diagnostic less useful) or if we're going to emit a raw error.
> + if (!R.getLocation().isValid() || ShouldAbort)
> + R << (" (in function: " + MF.getName() + ")").str();
> +
> + if (ShouldAbort)
> + report_fatal_error(R.getMsg());
> +
> + ORE.emit(R);
> +}
> +
> void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
> BasicBlock::const_iterator End,
> bool &HadTailCall) {
> @@ -1164,116 +1081,6 @@
> !FuncInfo->isExportedInst(I); // Exported instrs must be computed.
> }
>
> -#ifndef NDEBUG
> -// Collect per Instruction statistics for fast-isel misses. Only those
> -// instructions that cause the bail are accounted for. It does not account for
> -// instructions higher in the block. Thus, summing the per instructions stats
> -// will not add up to what is reported by NumFastIselFailures.
> -static void collectFailStats(const Instruction *I) {
> - switch (I->getOpcode()) {
> - default: assert(false && "<Invalid operator>");
> -
> - // Terminators
> - case Instruction::Ret: NumFastIselFailRet++; return;
> - case Instruction::Br: NumFastIselFailBr++; return;
> - case Instruction::Switch: NumFastIselFailSwitch++; return;
> - case Instruction::IndirectBr: NumFastIselFailIndirectBr++; return;
> - case Instruction::Invoke: NumFastIselFailInvoke++; return;
> - case Instruction::Resume: NumFastIselFailResume++; return;
> - case Instruction::Unreachable: NumFastIselFailUnreachable++; return;
> -
> - // Standard binary operators...
> - case Instruction::Add: NumFastIselFailAdd++; return;
> - case Instruction::FAdd: NumFastIselFailFAdd++; return;
> - case Instruction::Sub: NumFastIselFailSub++; return;
> - case Instruction::FSub: NumFastIselFailFSub++; return;
> - case Instruction::Mul: NumFastIselFailMul++; return;
> - case Instruction::FMul: NumFastIselFailFMul++; return;
> - case Instruction::UDiv: NumFastIselFailUDiv++; return;
> - case Instruction::SDiv: NumFastIselFailSDiv++; return;
> - case Instruction::FDiv: NumFastIselFailFDiv++; return;
> - case Instruction::URem: NumFastIselFailURem++; return;
> - case Instruction::SRem: NumFastIselFailSRem++; return;
> - case Instruction::FRem: NumFastIselFailFRem++; return;
> -
> - // Logical operators...
> - case Instruction::And: NumFastIselFailAnd++; return;
> - case Instruction::Or: NumFastIselFailOr++; return;
> - case Instruction::Xor: NumFastIselFailXor++; return;
> -
> - // Memory instructions...
> - case Instruction::Alloca: NumFastIselFailAlloca++; return;
> - case Instruction::Load: NumFastIselFailLoad++; return;
> - case Instruction::Store: NumFastIselFailStore++; return;
> - case Instruction::AtomicCmpXchg: NumFastIselFailAtomicCmpXchg++; return;
> - case Instruction::AtomicRMW: NumFastIselFailAtomicRMW++; return;
> - case Instruction::Fence: NumFastIselFailFence++; return;
> - case Instruction::GetElementPtr: NumFastIselFailGetElementPtr++; return;
> -
> - // Convert instructions...
> - case Instruction::Trunc: NumFastIselFailTrunc++; return;
> - case Instruction::ZExt: NumFastIselFailZExt++; return;
> - case Instruction::SExt: NumFastIselFailSExt++; return;
> - case Instruction::FPTrunc: NumFastIselFailFPTrunc++; return;
> - case Instruction::FPExt: NumFastIselFailFPExt++; return;
> - case Instruction::FPToUI: NumFastIselFailFPToUI++; return;
> - case Instruction::FPToSI: NumFastIselFailFPToSI++; return;
> - case Instruction::UIToFP: NumFastIselFailUIToFP++; return;
> - case Instruction::SIToFP: NumFastIselFailSIToFP++; return;
> - case Instruction::IntToPtr: NumFastIselFailIntToPtr++; return;
> - case Instruction::PtrToInt: NumFastIselFailPtrToInt++; return;
> - case Instruction::BitCast: NumFastIselFailBitCast++; return;
> -
> - // Other instructions...
> - case Instruction::ICmp: NumFastIselFailICmp++; return;
> - case Instruction::FCmp: NumFastIselFailFCmp++; return;
> - case Instruction::PHI: NumFastIselFailPHI++; return;
> - case Instruction::Select: NumFastIselFailSelect++; return;
> - case Instruction::Call: {
> - if (auto const *Intrinsic = dyn_cast<IntrinsicInst>(I)) {
> - switch (Intrinsic->getIntrinsicID()) {
> - default:
> - NumFastIselFailIntrinsicCall++; return;
> - case Intrinsic::sadd_with_overflow:
> - NumFastIselFailSAddWithOverflow++; return;
> - case Intrinsic::uadd_with_overflow:
> - NumFastIselFailUAddWithOverflow++; return;
> - case Intrinsic::ssub_with_overflow:
> - NumFastIselFailSSubWithOverflow++; return;
> - case Intrinsic::usub_with_overflow:
> - NumFastIselFailUSubWithOverflow++; return;
> - case Intrinsic::smul_with_overflow:
> - NumFastIselFailSMulWithOverflow++; return;
> - case Intrinsic::umul_with_overflow:
> - NumFastIselFailUMulWithOverflow++; return;
> - case Intrinsic::frameaddress:
> - NumFastIselFailFrameaddress++; return;
> - case Intrinsic::sqrt:
> - NumFastIselFailSqrt++; return;
> - case Intrinsic::experimental_stackmap:
> - NumFastIselFailStackMap++; return;
> - case Intrinsic::experimental_patchpoint_void: // fall-through
> - case Intrinsic::experimental_patchpoint_i64:
> - NumFastIselFailPatchPoint++; return;
> - }
> - }
> - NumFastIselFailCall++;
> - return;
> - }
> - case Instruction::Shl: NumFastIselFailShl++; return;
> - case Instruction::LShr: NumFastIselFailLShr++; return;
> - case Instruction::AShr: NumFastIselFailAShr++; return;
> - case Instruction::VAArg: NumFastIselFailVAArg++; return;
> - case Instruction::ExtractElement: NumFastIselFailExtractElement++; return;
> - case Instruction::InsertElement: NumFastIselFailInsertElement++; return;
> - case Instruction::ShuffleVector: NumFastIselFailShuffleVector++; return;
> - case Instruction::ExtractValue: NumFastIselFailExtractValue++; return;
> - case Instruction::InsertValue: NumFastIselFailInsertValue++; return;
> - case Instruction::LandingPad: NumFastIselFailLandingPad++; return;
> - }
> -}
> -#endif // NDEBUG
> -
> /// Set up SwiftErrorVals by going through the function. If the function has
> /// swifterror argument, it will be the first entry.
> static void setupSwiftErrorVals(const Function &Fn, const TargetLowering *TLI,
> @@ -1491,8 +1298,13 @@
> FastISelFailed = true;
> // Fast isel failed to lower these arguments
> ++NumFastIselFailLowerArguments;
> - if (EnableFastISelAbort > 1)
> - report_fatal_error("FastISel didn't lower all arguments");
> +
> + OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
> + Fn.getSubprogram(),
> + &Fn.getEntryBlock());
> + R << "FastISel didn't lower all arguments: "
> + << ore::NV("Prototype", Fn.getType());
> + reportFastISelFailure(*MF, *ORE, R, EnableFastISelAbort > 1);
>
> // Use SelectionDAG argument lowering
> LowerArguments(Fn);
> @@ -1601,22 +1413,22 @@
> continue;
> }
>
> -#ifndef NDEBUG
> - if (EnableFastISelVerbose2)
> - collectFailStats(Inst);
> -#endif
> -
> // Then handle certain instructions as single-LLVM-Instruction blocks.
> if (isa<CallInst>(Inst)) {
> + OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
> + Inst->getDebugLoc(), LLVMBB);
>
> - if (EnableFastISelVerbose || EnableFastISelAbort) {
> - dbgs() << "FastISel missed call: ";
> - Inst->print(dbgs());
> + R << "FastISel missed call";
> +
> + if (R.isEnabled() || EnableFastISelAbort) {
> + std::string InstStrStorage;
> + raw_string_ostream InstStr(InstStrStorage);
> + InstStr << *Inst;
> +
> + R << ": " << InstStr.str();
> }
> - if (EnableFastISelAbort > 2)
> - // FastISel selector couldn't handle something and bailed.
> - // For the purpose of debugging, just abort.
> - report_fatal_error("FastISel didn't select the entire block");
> +
> + reportFastISelFailure(*MF, *ORE, R, EnableFastISelAbort > 2);
>
> if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() &&
> !Inst->use_empty()) {
> @@ -1645,22 +1457,27 @@
> continue;
> }
>
> + OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
> + Inst->getDebugLoc(), LLVMBB);
> +
> bool ShouldAbort = EnableFastISelAbort;
> - if (EnableFastISelVerbose || EnableFastISelAbort) {
> - if (isa<TerminatorInst>(Inst)) {
> - // Use a different message for terminator misses.
> - dbgs() << "FastISel missed terminator: ";
> - // Don't abort unless for terminator unless the level is really high
> - ShouldAbort = (EnableFastISelAbort > 2);
> - } else {
> - dbgs() << "FastISel miss: ";
> - }
> - Inst->print(dbgs());
> + if (isa<TerminatorInst>(Inst)) {
> + // Use a different message for terminator misses.
> + R << "FastISel missed terminator";
> + // Don't abort for terminator unless the level is really high
> + ShouldAbort = (EnableFastISelAbort > 2);
> + } else {
> + R << "FastISel missed";
> }
> - if (ShouldAbort)
> - // FastISel selector couldn't handle something and bailed.
> - // For the purpose of debugging, just abort.
> - report_fatal_error("FastISel didn't select the entire block");
> +
> + if (R.isEnabled() || EnableFastISelAbort) {
> + std::string InstStrStorage;
> + raw_string_ostream InstStr(InstStrStorage);
> + InstStr << *Inst;
> + R << ": " << InstStr.str();
> + }
> +
> + reportFastISelFailure(*MF, *ORE, R, ShouldAbort);
>
> NumFastIselFailures += NumFastIselRemaining;
> break;
> Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> @@ -871,11 +871,13 @@
> DbgInfo = new SDDbgInfo();
> }
>
> -void SelectionDAG::init(MachineFunction &mf) {
> - MF = &mf;
> +void SelectionDAG::init(MachineFunction &NewMF,
> + OptimizationRemarkEmitter &NewORE) {
> + MF = &NewMF;
> + ORE = &NewORE;
> TLI = getSubtarget().getTargetLowering();
> TSI = getSubtarget().getSelectionDAGInfo();
> - Context = &mf.getFunction()->getContext();
> + Context = &MF->getFunction()->getContext();
> }
>
> SelectionDAG::~SelectionDAG() {
> Index: include/llvm/CodeGen/SelectionDAGISel.h
> ===================================================================
> --- include/llvm/CodeGen/SelectionDAGISel.h
> +++ include/llvm/CodeGen/SelectionDAGISel.h
> @@ -20,6 +20,7 @@
> #include "llvm/IR/BasicBlock.h"
> #include "llvm/Pass.h"
> #include "llvm/Target/TargetSubtargetInfo.h"
> +#include <memory>
>
> namespace llvm {
> class FastISel;
> @@ -29,6 +30,7 @@
> class MachineBasicBlock;
> class MachineFunction;
> class MachineInstr;
> + class OptimizationRemarkEmitter;
> class TargetLowering;
> class TargetLibraryInfo;
> class FunctionLoweringInfo;
> @@ -56,6 +58,10 @@
> bool FastISelFailed;
> SmallPtrSet<const Instruction *, 4> ElidedArgCopyInstrs;
>
> + /// Current optimization remark emitter.
> + /// Used to report things like combines and FastISel failures.
> + std::unique_ptr<OptimizationRemarkEmitter> ORE;
> +
> static char ID;
>
> explicit SelectionDAGISel(TargetMachine &tm,
> Index: include/llvm/CodeGen/SelectionDAG.h
> ===================================================================
> --- include/llvm/CodeGen/SelectionDAG.h
> +++ include/llvm/CodeGen/SelectionDAG.h
> @@ -36,6 +36,7 @@
> class MachineConstantPoolValue;
> class MachineFunction;
> class MDNode;
> +class OptimizationRemarkEmitter;
> class SDDbgValue;
> class TargetLowering;
> class SelectionDAGTargetInfo;
> @@ -171,6 +172,10 @@
> LLVMContext *Context;
> CodeGenOpt::Level OptLevel;
>
> + /// The function-level optimization remark emitter. Used to emit remarks
> + /// whenever manipulating the DAG.
> + OptimizationRemarkEmitter *ORE;
> +
> /// The starting token.
> SDNode EntryNode;
>
> @@ -318,7 +323,7 @@
> ~SelectionDAG();
>
> /// Prepare this SelectionDAG to process code in the given MachineFunction.
> - void init(MachineFunction &mf);
> + void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE);
>
> /// Clear state and free memory necessary to make this
> /// SelectionDAG ready to process a new block.
> @@ -331,6 +336,7 @@
> const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
> const SelectionDAGTargetInfo &getSelectionDAGInfo() const { return *TSI; }
> LLVMContext *getContext() const {return Context; }
> + OptimizationRemarkEmitter &getORE() const { return *ORE; }
>
> /// Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
> void viewGraph(const std::string &Title);
More information about the llvm-commits
mailing list