Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/Analysis/InlineCost.h b/linux-x64/clang/include/llvm/Analysis/InlineCost.h
index 611c9de..7f04a8c 100644
--- a/linux-x64/clang/include/llvm/Analysis/InlineCost.h
+++ b/linux-x64/clang/include/llvm/Analysis/InlineCost.h
@@ -27,6 +27,7 @@
class Function;
class ProfileSummaryInfo;
class TargetTransformInfo;
+class TargetLibraryInfo;
namespace InlineConstants {
// Various thresholds used by inline cost analysis.
@@ -48,7 +49,10 @@
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
-}
+/// Do not inline dynamic allocas that have been constant propagated to be
+/// static allocas above this amount in bytes.
+const uint64_t MaxSimplifiedDynamicAllocaToInline = 65536;
+} // namespace InlineConstants
/// Represents the cost of inlining a function.
///
@@ -61,16 +65,13 @@
/// directly tested to determine if inlining should occur given the cost and
/// threshold for this cost metric.
class InlineCost {
- enum SentinelValues {
- AlwaysInlineCost = INT_MIN,
- NeverInlineCost = INT_MAX
- };
+ enum SentinelValues { AlwaysInlineCost = INT_MIN, NeverInlineCost = INT_MAX };
/// The estimated cost of inlining this callsite.
- int Cost;
+ int Cost = 0;
/// The adjusted threshold against which this cost was computed.
- int Threshold;
+ int Threshold = 0;
/// Must be set for Always and Never instances.
const char *Reason = nullptr;
@@ -96,9 +97,7 @@
}
/// Test whether the inline cost is low enough for inlining.
- explicit operator bool() const {
- return Cost < Threshold;
- }
+ explicit operator bool() const { return Cost < Threshold; }
bool isAlways() const { return Cost == AlwaysInlineCost; }
bool isNever() const { return Cost == NeverInlineCost; }
@@ -131,14 +130,22 @@
};
/// InlineResult is basically true or false. For false results the message
-/// describes a reason why it is decided not to inline.
-struct InlineResult {
- const char *message = nullptr;
- InlineResult(bool result, const char *message = nullptr)
- : message(result ? nullptr : (message ? message : "cost > threshold")) {}
- InlineResult(const char *message = nullptr) : message(message) {}
- operator bool() const { return !message; }
- operator const char *() const { return message; }
+/// describes a reason.
+class InlineResult {
+ const char *Message = nullptr;
+ InlineResult(const char *Message = nullptr) : Message(Message) {}
+
+public:
+ static InlineResult success() { return {}; }
+ static InlineResult failure(const char *Reason) {
+ return InlineResult(Reason);
+ }
+ bool isSuccess() const { return Message == nullptr; }
+ const char *getFailureReason() const {
+ assert(!isSuccess() &&
+ "getFailureReason should only be called in failure cases");
+ return Message;
+ }
};
/// Thresholds to tune inline cost analysis. The inline cost analysis decides
@@ -152,7 +159,7 @@
struct InlineParams {
/// The default threshold to start with for a callee.
- int DefaultThreshold;
+ int DefaultThreshold = -1;
/// Threshold to use for callees with inline hint.
Optional<int> HintThreshold;
@@ -178,6 +185,9 @@
/// Compute inline cost even when the cost has exceeded the threshold.
Optional<bool> ComputeFullInlineCost;
+
+ /// Indicate whether we should allow inline deferral.
+ Optional<bool> EnableDeferral = true;
};
/// Generate the parameters to tune the inline cost analysis based only on the
@@ -212,11 +222,14 @@
///
/// Also note that calling this function *dynamically* computes the cost of
/// inlining the callsite. It is an expensive, heavyweight call.
-InlineCost getInlineCost(
- CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI,
- std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
- Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE = nullptr);
+InlineCost
+getInlineCost(CallBase &Call, const InlineParams &Params,
+ TargetTransformInfo &CalleeTTI,
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
/// Get an InlineCost with the callee explicitly specified.
/// This allows you to calculate the cost of inlining a function via a
@@ -226,12 +239,51 @@
InlineCost
getInlineCost(CallBase &Call, Function *Callee, const InlineParams &Params,
TargetTransformInfo &CalleeTTI,
- std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
- Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE);
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
+
+/// Returns InlineResult::success() if the call site should be always inlined
+/// because of user directives, and the inlining is viable. Returns
+/// InlineResult::failure() if the inlining may never happen because of user
+/// directives or incompatibilities detectable without needing callee traversal.
+/// Otherwise returns None, meaning that inlining should be decided based on
+/// other criteria (e.g. cost modeling).
+Optional<InlineResult> getAttributeBasedInliningDecision(
+ CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
+
+/// Get the cost estimate ignoring thresholds. This is similar to getInlineCost
+/// when passed InlineParams::ComputeFullInlineCost, or a non-null ORE. It
+/// uses default InlineParams otherwise.
+/// Contrary to getInlineCost, which makes a threshold-based final evaluation of
+/// should/shouldn't inline, captured in InlineResult, getInliningCostEstimate
+/// returns:
+/// - None, if the inlining cannot happen (is illegal)
+/// - an integer, representing the cost.
+Optional<int> getInliningCostEstimate(
+ CallBase &Call, TargetTransformInfo &CalleeTTI,
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
/// Minimal filter to detect invalid constructs for inlining.
InlineResult isInlineViable(Function &Callee);
-}
+
+// This pass is used to annotate instructions during the inline process for
+// debugging and analysis. The main purpose of the pass is to see and test
+// inliner's decisions when creating new optimizations to InlineCost.
+struct InlineCostAnnotationPrinterPass
+ : PassInfoMixin<InlineCostAnnotationPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit InlineCostAnnotationPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+} // namespace llvm
#endif