Start cleaning up the InlineCost class. This switches to sentinel values

rather than a bitfield, a great suggestion by Chris during code review.

There is still quite a bit of cruft in the interface, but that requires
sorting out some awkward uses of the cost inside the actual inliner.

No functionality changed intended here.

llvm-svn: 153853
This commit is contained in:
Chandler Carruth 2012-04-01 22:44:09 +00:00
parent 3ecfa7b277
commit 219173a1be
1 changed files with 20 additions and 25 deletions

View File

@ -49,59 +49,54 @@ namespace llvm {
/// directly tested to determine if inlining should occur given the cost and /// directly tested to determine if inlining should occur given the cost and
/// threshold for this cost metric. /// threshold for this cost metric.
class InlineCost { class InlineCost {
enum CostKind { enum SentinelValues {
CK_Variable, AlwaysInlineCost = INT_MIN,
CK_Always, NeverInlineCost = INT_MAX
CK_Never
}; };
const int Cost : 30; // The inlining cost if neither always nor never. /// \brief The estimated cost of inlining this callsite.
const unsigned Kind : 2; // The type of cost, one of CostKind above. const int Cost;
/// \brief The adjusted threshold against which this cost should be tested. /// \brief The adjusted threshold against which this cost was computed.
const int Threshold; const int Threshold;
// Trivial constructor, interesting logic in the factory functions below. // Trivial constructor, interesting logic in the factory functions below.
InlineCost(int Cost, CostKind Kind, int Threshold) InlineCost(int Cost, int Threshold)
: Cost(Cost), Kind(Kind), Threshold(Threshold) {} : Cost(Cost), Threshold(Threshold) {}
public: public:
static InlineCost get(int Cost, int Threshold) { static InlineCost get(int Cost, int Threshold) {
InlineCost Result(Cost, CK_Variable, Threshold); assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
assert(Result.Cost == Cost && "Cost exceeds InlineCost precision"); assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
return Result; return InlineCost(Cost, Threshold);
} }
static InlineCost getAlways() { static InlineCost getAlways() {
return InlineCost(0, CK_Always, 0); return InlineCost(AlwaysInlineCost, 0);
} }
static InlineCost getNever() { static InlineCost getNever() {
return InlineCost(0, CK_Never, 0); return InlineCost(NeverInlineCost, 0);
} }
/// \brief Test whether the inline cost is low enough for inlining. /// \brief Test whether the inline cost is low enough for inlining.
operator bool() const { operator bool() const {
if (isAlways()) return true;
if (isNever()) return false;
return Cost < Threshold; return Cost < Threshold;
} }
bool isVariable() const { return Kind == CK_Variable; } bool isAlways() const { return Cost == AlwaysInlineCost; }
bool isAlways() const { return Kind == CK_Always; } bool isNever() const { return Cost == NeverInlineCost; }
bool isNever() const { return Kind == CK_Never; } bool isVariable() const { return !isAlways() && !isNever(); }
/// getCost() - Return a "variable" inline cost's amount. It is /// \brief Get the inline cost estimate.
/// an error to call this on an "always" or "never" InlineCost. /// It is an error to call this on an "always" or "never" InlineCost.
int getCost() const { int getCost() const {
assert(Kind == CK_Variable && "Invalid access of InlineCost"); assert(isVariable() && "Invalid access of InlineCost");
return Cost; return Cost;
} }
/// \brief Get the cost delta from the threshold for inlining. /// \brief Get the cost delta from the threshold for inlining.
/// Only valid if the cost is of the variable kind. Returns a negative /// Only valid if the cost is of the variable kind. Returns a negative
/// value if the cost is too high to inline. /// value if the cost is too high to inline.
int getCostDelta() const { int getCostDelta() const { return Threshold - getCost(); }
return Threshold - getCost();
}
}; };
/// InlineCostAnalyzer - Cost analyzer used by inliner. /// InlineCostAnalyzer - Cost analyzer used by inliner.