llvm.org GIT mirror llvm / 645cd31
[ThinLTO] Split NotEligibleToImport into legality and inlinability flags Summary: The NotEligibleToImport flag on the GlobalValueSummary was set if it isn't legal to import (e.g. because it references unpromotable locals) and when it can't be inlined (in which case importing is pointless). I split out the inlinable piece into a separate flag on the FunctionSummary (doesn't make sense for aliases or global variables), because in the future we may want to import for reasons other than inlining. Reviewers: davidxl Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, arphaman, llvm-commits Differential Revision: https://reviews.llvm.org/D53345 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346261 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 11 months ago
14 changed file(s) with 52 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
477477 TypeCheckedLoadConstVCalls;
478478 };
479479
480 /// Function attribute flags. Used to track if a function accesses memory,
481 /// recurses or aliases.
480 /// Flags specific to function summaries.
482481 struct FFlags {
482 // Function attribute flags. Used to track if a function accesses memory,
483 // recurses or aliases.
483484 unsigned ReadNone : 1;
484485 unsigned ReadOnly : 1;
485486 unsigned NoRecurse : 1;
486487 unsigned ReturnDoesNotAlias : 1;
488
489 // Indicate if the global value cannot be inlined.
490 unsigned NoInline : 1;
487491 };
488492
489493 /// Create an empty FunctionSummary (with specified call edges).
510514 /// during the initial compile step when the summary index is first built.
511515 unsigned InstCount;
512516
513 /// Function attribute flags. Used to track if a function accesses memory,
514 /// recurses or aliases.
517 /// Function summary specific flags.
515518 FFlags FunFlags;
516519
517520 /// List of call edge pairs from this function.
545548 return GVS->getSummaryKind() == FunctionKind;
546549 }
547550
548 /// Get function attribute flags.
551 /// Get function summary flags.
549552 FFlags fflags() const { return FunFlags; }
550553
551554 /// Get the instruction count recorded for this function.
5555 // to find at least one summary for the GUID that is global or a local
5656 // in the referenced module for direct calls.
5757 LocalLinkageNotInModule,
58 // This corresponse to the NotEligibleToImport being set on the summary,
58 // This corresponds to the NotEligibleToImport being set on the summary,
5959 // which can happen in a few different cases (e.g. local that can't be
6060 // renamed or promoted because it is referenced on a llvm*.used variable).
61 NotEligible
61 NotEligible,
62 // This corresponds to NoInline being set on the function summary,
63 // which will happen if it is known that the inliner will not be able
64 // to inline the function (e.g. it is marked with a NoInline attribute).
65 NoInline
6266 };
6367
6468 /// Information optionally tracked for candidates the importer decided
349349
350350 bool NonRenamableLocal = isNonRenamableLocal(F);
351351 bool NotEligibleForImport =
352 NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
353 // Inliner doesn't handle variadic functions.
354 // FIXME: refactor this to use the same code that inliner is using.
355 F.isVarArg() ||
356 // Don't try to import functions with noinline attribute.
357 F.getAttributes().hasFnAttribute(Attribute::NoInline);
352 NonRenamableLocal || HasInlineAsmMaybeReferencingInternal;
358353 GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
359354 /* Live = */ false, F.isDSOLocal());
360355 FunctionSummary::FFlags FunFlags{
361356 F.hasFnAttribute(Attribute::ReadNone),
362357 F.hasFnAttribute(Attribute::ReadOnly),
363 F.hasFnAttribute(Attribute::NoRecurse),
364 F.returnDoesNotAlias(),
365 };
358 F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(),
359 // Inliner doesn't handle variadic functions.
360 // FIXME: refactor this to use the same code that inliner is using.
361 F.isVarArg() ||
362 // Don't try to import functions with noinline attribute.
363 F.getAttributes().hasFnAttribute(Attribute::NoInline)};
366364 auto FuncSummary = llvm::make_unique(
367365 Flags, NumInsts, FunFlags, RefEdges.takeVector(),
368366 CallGraphEdges.takeVector(), TypeTests.takeVector(),
477475 F->hasFnAttribute(Attribute::ReadNone),
478476 F->hasFnAttribute(Attribute::ReadOnly),
479477 F->hasFnAttribute(Attribute::NoRecurse),
480 F->returnDoesNotAlias()},
478 F->returnDoesNotAlias(),
479 /* NoInline = */ false},
481480 ArrayRef{}, ArrayRef{},
482481 ArrayRef{},
483482 ArrayRef{},
739739 KEYWORD(readOnly);
740740 KEYWORD(noRecurse);
741741 KEYWORD(returnDoesNotAlias);
742 KEYWORD(noInline);
742743 KEYWORD(calls);
743744 KEYWORD(callee);
744745 KEYWORD(hotness);
77137713 /// := 'funcFlags' ':' '(' ['readNone' ':' Flag]?
77147714 /// [',' 'readOnly' ':' Flag]? [',' 'noRecurse' ':' Flag]?
77157715 /// [',' 'returnDoesNotAlias' ':' Flag]? ')'
7716 /// [',' 'noInline' ':' Flag]? ')'
77167717 bool LLParser::ParseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
77177718 assert(Lex.getKind() == lltok::kw_funcFlags);
77187719 Lex.Lex();
77477748 if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Val))
77487749 return true;
77497750 FFlags.ReturnDoesNotAlias = Val;
7751 break;
7752 case lltok::kw_noInline:
7753 Lex.Lex();
7754 if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Val))
7755 return true;
7756 FFlags.NoInline = Val;
77507757 break;
77517758 default:
77527759 return Error(Lex.getLoc(), "expected function flag type");
368368 kw_readOnly,
369369 kw_noRecurse,
370370 kw_returnDoesNotAlias,
371 kw_noInline,
371372 kw_calls,
372373 kw_callee,
373374 kw_hotness,
875875 Flags.ReadOnly = (RawFlags >> 1) & 0x1;
876876 Flags.NoRecurse = (RawFlags >> 2) & 0x1;
877877 Flags.ReturnDoesNotAlias = (RawFlags >> 3) & 0x1;
878 Flags.NoInline = (RawFlags >> 4) & 0x1;
878879 return Flags;
879880 }
880881
970970 RawFlags |= (Flags.ReadOnly << 1);
971971 RawFlags |= (Flags.NoRecurse << 2);
972972 RawFlags |= (Flags.ReturnDoesNotAlias << 3);
973 RawFlags |= (Flags.NoInline << 4);
973974 return RawFlags;
974975 }
975976
28702870 Out << ", readOnly: " << FFlags.ReadOnly;
28712871 Out << ", noRecurse: " << FFlags.NoRecurse;
28722872 Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias;
2873 Out << ", noInline: " << FFlags.NoInline;
28732874 Out << ")";
28742875 }
28752876 if (!FS->calls().empty()) {
181181
182182 static std::string fflagsToString(FunctionSummary::FFlags F) {
183183 auto FlagValue = [](unsigned V) { return V ? '1' : '0'; };
184 char FlagRep[] = {FlagValue(F.ReadNone), FlagValue(F.ReadOnly),
185 FlagValue(F.NoRecurse), FlagValue(F.ReturnDoesNotAlias), 0};
184 char FlagRep[] = {FlagValue(F.ReadNone), FlagValue(F.ReadOnly),
185 FlagValue(F.NoRecurse), FlagValue(F.ReturnDoesNotAlias),
186 FlagValue(F.NoInline), 0};
186187
187188 return FlagRep;
188189 }
236236 return false;
237237 }
238238
239 // Skip if it isn't legal to import (e.g. may reference unpromotable
240 // locals).
239241 if (Summary->notEligibleToImport()) {
240242 Reason = FunctionImporter::ImportFailureReason::NotEligible;
243 return false;
244 }
245
246 // Don't bother importing if we can't inline it anyway.
247 if (Summary->fflags().NoInline) {
248 Reason = FunctionImporter::ImportFailureReason::NoInline;
241249 return false;
242250 }
243251
317325 return "LocalLinkageNotInModule";
318326 case FunctionImporter::ImportFailureReason::NotEligible:
319327 return "NotEligible";
328 case FunctionImporter::ImportFailureReason::NoInline:
329 return "NoInline";
320330 }
321331 llvm_unreachable("invalid reason");
322332 }
8080 ; CHECK: ^13 = gv: (guid: 12, summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0))))
8181 ; CHECK: ^14 = gv: (guid: 13, summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 1))))
8282 ; CHECK: ^15 = gv: (guid: 14, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 1, live: 1, dsoLocal: 0), insts: 1)))
83 ; CHECK: ^16 = gv: (guid: 15, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 1, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0))))
84 ; CHECK: ^17 = gv: (guid: 16, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 0, readOnly: 1, noRecurse: 0, returnDoesNotAlias: 1), calls: ((callee: ^15)))))
83 ; CHECK: ^16 = gv: (guid: 15, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 1, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0, noInline: 0))))
84 ; CHECK: ^17 = gv: (guid: 16, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 0, readOnly: 1, noRecurse: 0, returnDoesNotAlias: 1, noInline: 0), calls: ((callee: ^15)))))
8585 ; CHECK: ^18 = gv: (guid: 17, summaries: (alias: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 1), aliasee: ^14)))
8686 ; CHECK: ^19 = gv: (guid: 18, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 4, typeIdInfo: (typeTests: (^24, ^26)))))
8787 ; CHECK: ^20 = gv: (guid: 19, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 8, typeIdInfo: (typeTestAssumeVCalls: (vFuncId: (^27, offset: 16))))))
1919 ; BC-NEXT:
2020 ; BC-NEXT:
2121 ; BC-NEXT:
22 ; BC-NEXT: 16
22 ; BC-NEXT: 0 op2=1 op3=16
2323 ; BC-NEXT:
2424 ; BC-NEXT:
2525 ; BC:
3333 ; CLUSTER1: // Module: {{.*}}2.bc
3434 ; CLUSTER1-NEXT: subgraph cluster_1 {
3535 ; CLUSTER1-DAG: M1_[[A:[0-9]+]] [{{.*}}A|extern{{.*}}]; // variable
36 ; CLUSTER1-DAG: M1_[[FOO:[0-9]+]] [{{.*}}foo|extern{{.*}}]; // function, not eligible to import
36 ; CLUSTER1-DAG: M1_[[FOO:[0-9]+]] [{{.*}}foo|extern{{.*}} ffl: 00001{{.*}}]; // function
3737 ; CLUSTER1-DAG: M1_[[B:[0-9]+]] [{{.*}}B|extern{{.*}}]; // variable
3838 ; CLUSTER1-DAG: M1_[[BAR:[0-9]+]] [{{.*}}bar|extern{{.*}}]; // function, dead
3939 ; CLUSTER1-NEXT: // Edges: