diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2018-06-22 05:33:57 +0000 |
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2018-06-22 05:33:57 +0000 |
| commit | aa5f4d2e23d34ac08cb7eb0f8810cc9db4760f3a (patch) | |
| tree | 32995cfb3509dd029317810a8d385ae038ec2823 | |
| parent | 6af73076505d9a845740c99b0fb89898dab36797 (diff) | |
| download | bcm5719-llvm-aa5f4d2e23d34ac08cb7eb0f8810cc9db4760f3a.tar.gz bcm5719-llvm-aa5f4d2e23d34ac08cb7eb0f8810cc9db4760f3a.zip | |
Revert r335306 (and r335314) - the Call Graph Profile pass.
This is the first pass in the main pipeline to use the legacy PM's
ability to run function analyses "on demand". Unfortunately, it turns
out there are bugs in that somewhat-hacky approach. At the very least,
it leaks memory and doesn't support -debug-pass=Structure. Unclear if
there are larger issues or not, but this should get the sanitizer bots
back to green by fixing the memory leaks.
llvm-svn: 335320
| -rw-r--r-- | llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h | 3 | ||||
| -rw-r--r-- | llvm/include/llvm/InitializePasses.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/LinkAllPasses.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/Transforms/Instrumentation.h | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 54 | ||||
| -rw-r--r-- | llvm/lib/IR/Verifier.cpp | 20 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/PassManagerBuilder.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/CGProfile.cpp | 110 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/Instrumentation.cpp | 1 | ||||
| -rw-r--r-- | llvm/test/Instrumentation/cgprofile.ll | 28 | ||||
| -rw-r--r-- | llvm/test/MC/ELF/cgprofile.ll | 50 | ||||
| -rw-r--r-- | llvm/test/Other/opt-O2-pipeline.ll | 4 | ||||
| -rw-r--r-- | llvm/test/Other/opt-O3-pipeline.ll | 4 | ||||
| -rw-r--r-- | llvm/test/Other/opt-Os-pipeline.ll | 4 | ||||
| -rw-r--r-- | llvm/test/Verifier/module-flags-cgprofile.ll | 30 |
16 files changed, 7 insertions, 308 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index fe14e8564ec..626703e46f6 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -36,14 +36,11 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { protected: MCSymbolRefExpr::VariantKind PLTRelativeVariantKind = MCSymbolRefExpr::VK_None; - const TargetMachine *TM; public: TargetLoweringObjectFileELF() = default; ~TargetLoweringObjectFileELF() override = default; - void Initialize(MCContext &Ctx, const TargetMachine &TM) override; - /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 2ca71350592..55132d38c20 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -94,7 +94,6 @@ void initializeCFGViewerLegacyPassPass(PassRegistry&); void initializeCFIInstrInserterPass(PassRegistry&); void initializeCFLAndersAAWrapperPassPass(PassRegistry&); void initializeCFLSteensAAWrapperPassPass(PassRegistry&); -void initializeCGProfilePassPass(PassRegistry&); void initializeCallGraphDOTPrinterPass(PassRegistry&); void initializeCallGraphPrinterLegacyPassPass(PassRegistry&); void initializeCallGraphViewerPass(PassRegistry&); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index 9c70c5b8577..a49c4aad865 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -80,7 +80,6 @@ namespace { (void) llvm::createCallGraphDOTPrinterPass(); (void) llvm::createCallGraphViewerPass(); (void) llvm::createCFGSimplificationPass(); - (void) llvm::createCGProfilePass(); (void) llvm::createCFLAndersAAWrapperPass(); (void) llvm::createCFLSteensAAWrapperPass(); (void) llvm::createStructurizeCFGPass(); diff --git a/llvm/include/llvm/Transforms/Instrumentation.h b/llvm/include/llvm/Transforms/Instrumentation.h index 994998afefa..4a346c8d745 100644 --- a/llvm/include/llvm/Transforms/Instrumentation.h +++ b/llvm/include/llvm/Transforms/Instrumentation.h @@ -187,8 +187,6 @@ struct SanitizerCoverageOptions { ModulePass *createSanitizerCoverageModulePass( const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()); -ModulePass *createCGProfilePass(); - /// Calculate what to divide by to scale counts. /// /// Given the maximum count, calculate a divisor that will scale all the diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 24ff42a34ff..df8aecd7cf4 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -91,12 +91,6 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, // ELF //===----------------------------------------------------------------------===// -void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, - const TargetMachine &TgtM) { - TargetLoweringObjectFile::Initialize(Ctx, TgtM); - TM = &TgtM; -} - void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { auto &C = getContext(); @@ -122,49 +116,15 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, StringRef Section; GetObjCImageInfo(M, Version, Flags, Section); - if (!Section.empty()) { - auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); - Streamer.SwitchSection(S); - Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); - Streamer.EmitIntValue(Version, 4); - Streamer.EmitIntValue(Flags, 4); - Streamer.AddBlankLine(); - } - - SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; - M.getModuleFlagsMetadata(ModuleFlags); - - MDNode *CFGProfile = nullptr; - - for (const auto &MFE : ModuleFlags) { - StringRef Key = MFE.Key->getString(); - if (Key == "CG Profile") { - CFGProfile = cast<MDNode>(MFE.Val); - break; - } - } - - if (!CFGProfile) + if (Section.empty()) return; - auto GetSym = [this](const MDOperand &MDO) { - auto V = cast<ValueAsMetadata>(MDO); - const Function *F = cast<Function>(V->getValue()); - return TM->getSymbol(F); - }; - - for (const auto &Edge : CFGProfile->operands()) { - MDNode *E = cast<MDNode>(Edge); - const MCSymbol *From = GetSym(E->getOperand(0)); - const MCSymbol *To = GetSym(E->getOperand(1)); - uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2)) - ->getValue() - ->getUniqueInteger() - .getZExtValue(); - Streamer.emitCGProfileEntry( - MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C), - MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count); - } + auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); + Streamer.SwitchSection(S); + Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); + Streamer.EmitIntValue(Version, 4); + Streamer.EmitIntValue(Flags, 4); + Streamer.AddBlankLine(); } MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 11af71142ef..dca9d9b64ff 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -409,7 +409,6 @@ private: void visitModuleFlag(const MDNode *Op, DenseMap<const MDString *, const MDNode *> &SeenIDs, SmallVectorImpl<const MDNode *> &Requirements); - void visitModuleFlagCGProfileEntry(const MDOperand &MDO); void visitFunction(const Function &F); void visitBasicBlock(BasicBlock &BB); void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); @@ -1412,25 +1411,6 @@ Verifier::visitModuleFlag(const MDNode *Op, Assert(M.getNamedMetadata("llvm.linker.options"), "'Linker Options' named metadata no longer supported"); } - - if (ID->getString() == "CG Profile") { - for (const MDOperand &MDO : cast<MDNode>(Op->getOperand(2))->operands()) - visitModuleFlagCGProfileEntry(MDO); - } -} - -void Verifier::visitModuleFlagCGProfileEntry(const MDOperand &MDO) { - auto Node = dyn_cast_or_null<MDNode>(MDO); - Assert(Node && Node->getNumOperands() == 3, "expected a MDNode triple", MDO); - auto From = dyn_cast_or_null<ValueAsMetadata>(Node->getOperand(0)); - Assert(From && isa<Function>(From->getValue()), "expected a Function", - Node->getOperand(0)); - auto To = dyn_cast_or_null<ValueAsMetadata>(Node->getOperand(1)); - Assert(To && isa<Function>(To->getValue()), "expected a Function", - Node->getOperand(1)); - auto Count = dyn_cast_or_null<ConstantAsMetadata>(Node->getOperand(2)); - Assert(Count && Count->getType()->isIntegerTy(), - "expected an integer constant", Node->getOperand(2)); } /// Return true if this attribute kind only applies to functions. diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index defb54e19bf..a2559bc70b1 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -694,8 +694,6 @@ void PassManagerBuilder::populateModulePassManager( MPM.add(createConstantMergePass()); // Merge dup global constants } - MPM.add(createCGProfilePass()); - if (MergeFunctions) MPM.add(createMergeFunctionsPass()); diff --git a/llvm/lib/Transforms/Instrumentation/CGProfile.cpp b/llvm/lib/Transforms/Instrumentation/CGProfile.cpp deleted file mode 100644 index cb1fcb21425..00000000000 --- a/llvm/lib/Transforms/Instrumentation/CGProfile.cpp +++ /dev/null @@ -1,110 +0,0 @@ -//===-- CGProfile.cpp -----------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/MapVector.h" -#include "llvm/Analysis/BlockFrequencyInfo.h" -#include "llvm/Analysis/BranchProbabilityInfo.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/MDBuilder.h" -#include "llvm/IR/PassManager.h" -#include "llvm/Transforms/Instrumentation.h" - -#include <array> - -using namespace llvm; - -class CGProfilePass : public ModulePass { -public: - static char ID; - - CGProfilePass() : ModulePass(ID) { - initializeCGProfilePassPass(*PassRegistry::getPassRegistry()); - } - - StringRef getPassName() const override { return "CGProfilePass"; } - -private: - bool runOnModule(Module &M) override; - bool addModuleFlags( - Module &M, - MapVector<std::pair<Function *, Function *>, uint64_t> &Counts) const; - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<BlockFrequencyInfoWrapperPass>(); - AU.addRequired<BranchProbabilityInfoWrapperPass>(); - } -}; - -bool CGProfilePass::runOnModule(Module &M) { - if (skipModule(M)) - return false; - - MapVector<std::pair<Function *, Function *>, uint64_t> Counts; - - for (auto &F : M) { - if (F.isDeclaration()) - continue; - getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI(); - auto &BFI = getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI(); - for (const auto &BB : F) { - Optional<uint64_t> BBCount = BFI.getBlockProfileCount(&BB); - if (!BBCount) - continue; - for (const auto &I : BB) { - auto *CI = dyn_cast<CallInst>(&I); - if (!CI) - continue; - Function *CalledF = CI->getCalledFunction(); - if (!CalledF || CalledF->isIntrinsic()) - continue; - - uint64_t &Count = Counts[std::make_pair(&F, CalledF)]; - Count = SaturatingAdd(Count, *BBCount); - } - } - } - - return addModuleFlags(M, Counts); -} - -bool CGProfilePass::addModuleFlags( - Module &M, - MapVector<std::pair<Function *, Function *>, uint64_t> &Counts) const { - if (Counts.empty()) - return false; - - LLVMContext &Context = M.getContext(); - MDBuilder MDB(Context); - std::vector<Metadata *> Nodes; - - for (auto E : Counts) { - SmallVector<Metadata *, 3> Vals; - Vals.push_back(ValueAsMetadata::get(E.first.first)); - Vals.push_back(ValueAsMetadata::get(E.first.second)); - Vals.push_back(MDB.createConstant( - ConstantInt::get(Type::getInt64Ty(Context), E.second))); - Nodes.push_back(MDNode::get(Context, Vals)); - } - - M.addModuleFlag(Module::Append, "CG Profile", MDNode::get(Context, Nodes)); - return true; -} - -char CGProfilePass::ID = 0; -INITIALIZE_PASS_BEGIN(CGProfilePass, "cg-profile", - "Generate profile information from the call graph.", - false, false) -INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass) -INITIALIZE_PASS_END(CGProfilePass, "cg-profile", - "Generate profile information from the call graph.", false, - false) - -ModulePass *llvm::createCGProfilePass() { return new CGProfilePass(); } diff --git a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt index 5d008482319..66fdcb3ccc4 100644 --- a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt +++ b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt @@ -1,7 +1,6 @@ add_llvm_library(LLVMInstrumentation AddressSanitizer.cpp BoundsChecking.cpp - CGProfile.cpp DataFlowSanitizer.cpp GCOVProfiling.cpp MemorySanitizer.cpp diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp index fbd651f3f20..8e9eea96ced 100644 --- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -60,7 +60,6 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) { initializeAddressSanitizerModulePass(Registry); initializeBoundsCheckingLegacyPassPass(Registry); initializeGCOVProfilerLegacyPassPass(Registry); - initializeCGProfilePassPass(Registry); initializePGOInstrumentationGenLegacyPassPass(Registry); initializePGOInstrumentationUseLegacyPassPass(Registry); initializePGOIndirectCallPromotionLegacyPassPass(Registry); diff --git a/llvm/test/Instrumentation/cgprofile.ll b/llvm/test/Instrumentation/cgprofile.ll deleted file mode 100644 index f515a511f84..00000000000 --- a/llvm/test/Instrumentation/cgprofile.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: opt < %s -cg-profile -S | FileCheck %s - -declare void @b() - -define void @a() !prof !1 { - call void @b() - ret void -} - -define void @freq(i1 %cond) !prof !1 { - br i1 %cond, label %A, label %B, !prof !2 -A: - call void @a(); - ret void -B: - call void @b(); - ret void -} - -!1 = !{!"function_entry_count", i64 32} -!2 = !{!"branch_weights", i32 5, i32 10} - -; CHECK: !llvm.module.flags = !{![[cgprof:[0-9]+]]} -; CHECK: ![[cgprof]] = !{i32 5, !"CG Profile", ![[prof:[0-9]+]]} -; CHECK: ![[prof]] = !{![[e0:[0-9]+]], ![[e1:[0-9]+]], ![[e2:[0-9]+]]} -; CHECK: ![[e0]] = !{void ()* @a, void ()* @b, i64 32} -; CHECK: ![[e1]] = !{void (i1)* @freq, void ()* @a, i64 11} -; CHECK: ![[e2]] = !{void (i1)* @freq, void ()* @b, i64 20} diff --git a/llvm/test/MC/ELF/cgprofile.ll b/llvm/test/MC/ELF/cgprofile.ll deleted file mode 100644 index 27b43f1172c..00000000000 --- a/llvm/test/MC/ELF/cgprofile.ll +++ /dev/null @@ -1,50 +0,0 @@ -; RUN: llc -filetype=asm %s -o - -mtriple x86_64-pc-linux-gnu | FileCheck %s -; RUN: llc -filetype=obj %s -o %t -mtriple x86_64-pc-linux-gnu -; RUN: llvm-readobj -elf-cg-profile %t | FileCheck %s --check-prefix=OBJ - -declare void @b() - -define void @a() { - call void @b() - ret void -} - -define void @freq(i1 %cond) { - br i1 %cond, label %A, label %B -A: - call void @a(); - ret void -B: - call void @b(); - ret void -} - -!llvm.module.flags = !{!0} - -!0 = !{i32 5, !"CG Profile", !1} -!1 = !{!2, !3, !4} -!2 = !{void ()* @a, void ()* @b, i64 32} -!3 = !{void (i1)* @freq, void ()* @a, i64 11} -!4 = !{void (i1)* @freq, void ()* @b, i64 20} - -; CHECK: .cg_profile a, b, 32 -; CHECK: .cg_profile freq, a, 11 -; CHECK: .cg_profile freq, b, 20 - -; OBJ: CGProfile [ -; OBJ: CGProfileEntry { -; OBJ: From: a -; OBJ: To: b -; OBJ: Weight: 32 -; OBJ: } -; OBJ: CGProfileEntry { -; OBJ: From: freq -; OBJ: To: a -; OBJ: Weight: 11 -; OBJ: } -; OBJ: CGProfileEntry { -; OBJ: From: freq -; OBJ: To: b -; OBJ: Weight: 20 -; OBJ: } -; OBJ:] diff --git a/llvm/test/Other/opt-O2-pipeline.ll b/llvm/test/Other/opt-O2-pipeline.ll index 17574abba34..96d9f22cc01 100644 --- a/llvm/test/Other/opt-O2-pipeline.ll +++ b/llvm/test/Other/opt-O2-pipeline.ll @@ -249,10 +249,6 @@ ; CHECK-NEXT: Strip Unused Function Prototypes ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: Merge Duplicate Global Constants -; CHECK-NEXT: CGProfilePass -; FIXME: This pass uses the magic "on-demand function analysis" feature of the -; legacy pass manager and doesn't correctly print pass names. -; CHECK-NEXT: Unnamed pass ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/Other/opt-O3-pipeline.ll b/llvm/test/Other/opt-O3-pipeline.ll index ab62dc96397..fc9f4fd6b31 100644 --- a/llvm/test/Other/opt-O3-pipeline.ll +++ b/llvm/test/Other/opt-O3-pipeline.ll @@ -253,10 +253,6 @@ ; CHECK-NEXT: Strip Unused Function Prototypes ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: Merge Duplicate Global Constants -; CHECK-NEXT: CGProfilePass -; FIXME: This pass uses the magic "on-demand function analysis" feature of the -; legacy pass manager and doesn't correctly print pass names. -; CHECK-NEXT: Unnamed pass ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/Other/opt-Os-pipeline.ll b/llvm/test/Other/opt-Os-pipeline.ll index 6e008a9be19..206a20a598e 100644 --- a/llvm/test/Other/opt-Os-pipeline.ll +++ b/llvm/test/Other/opt-Os-pipeline.ll @@ -235,10 +235,6 @@ ; CHECK-NEXT: Strip Unused Function Prototypes ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: Merge Duplicate Global Constants -; CHECK-NEXT: CGProfilePass -; FIXME: This pass uses the magic "on-demand function analysis" feature of the -; legacy pass manager and doesn't correctly print pass names. -; CHECK-NEXT: Unnamed pass ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/Verifier/module-flags-cgprofile.ll b/llvm/test/Verifier/module-flags-cgprofile.ll deleted file mode 100644 index 307c4f28705..00000000000 --- a/llvm/test/Verifier/module-flags-cgprofile.ll +++ /dev/null @@ -1,30 +0,0 @@ -; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s - -declare void @b() -declare void @a() - -!llvm.module.flags = !{!0} - -!0 = !{i32 5, !"CG Profile", !1} -!1 = !{!2, !"", !3, !4, !5, !6, !7, !8} -!2 = !{void ()* @a, void ()* @b, i64 32} -!3 = !{void ()* @a, void ()* @b} -!4 = !{void ()* @a, void ()* @b, i64 32, i64 32} -!5 = !{!"a", void ()* @b, i64 32} -!6 = !{void ()* @a, !"b", i64 32} -!7 = !{void ()* @a, void ()* @b, !""} -!8 = !{void ()* @a, void ()* @b, null} - -; CHECK: expected a MDNode triple -; CHECK: !"" -; CHECK: expected a MDNode triple -; CHECK: !3 = !{void ()* @a, void ()* @b} -; CHECK: expected a MDNode triple -; CHECK: !4 = !{void ()* @a, void ()* @b, i64 32, i64 32} -; CHECK: expected a Function -; CHECK: !"a" -; CHECK: expected a Function -; CHECK: !"b" -; CHECK: expected an integer constant -; CHECK: !"" -; CHECK: expected an integer constant |

