Optimistically inline Math.sqrt as unboxed sqrtsd instruction.

R=kmillikin@google.com
BUG=

Review URL: https://chromiumcodereview.appspot.com//10915200

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12200 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
vegorov@google.com 2012-09-11 14:52:32 +00:00
parent 0163d32763
commit 5f37ef55a5
5 changed files with 98 additions and 15 deletions

View file

@ -274,6 +274,16 @@ static void RemovePushArguments(InstanceCallInstr* call) {
}
static void RemovePushArguments(StaticCallInstr* call) {
// Remove original push arguments.
for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
PushArgumentInstr* push = call->ArgumentAt(i);
push->ReplaceUsesWith(push->value()->definition());
push->RemoveFromGraph();
}
}
// Returns true if all targets are the same.
// TODO(srdjan): if targets are native use their C_function to compare.
static bool HasOneTarget(const ICData& ic_data) {
@ -774,11 +784,13 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
}
void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* instr) {
void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) {
MethodRecognizer::Kind recognized_kind =
MethodRecognizer::RecognizeKind(instr->function());
MethodRecognizer::RecognizeKind(call->function());
if (recognized_kind == MethodRecognizer::kMathSqrt) {
instr->set_recognized(MethodRecognizer::kMathSqrt);
MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call);
call->ReplaceWith(sqrt, current_iterator());
RemovePushArguments(call);
}
}

View file

@ -1059,6 +1059,11 @@ RawAbstractType* UnboxedDoubleBinaryOpInstr::CompileType() const {
}
RawAbstractType* MathSqrtInstr::CompileType() const {
return Type::Double();
}
RawAbstractType* UnboxDoubleInstr::CompileType() const {
return Type::null();
}
@ -1468,18 +1473,12 @@ LocationSummary* StaticCallInstr::MakeLocationSummary() const {
void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Label done;
if (recognized() == MethodRecognizer::kMathSqrt) {
compiler->GenerateInlinedMathSqrt(&done);
// Falls through to static call when operand type is not double or smi.
}
compiler->GenerateStaticCall(deopt_id(),
token_pos(),
function(),
ArgumentCount(),
argument_names(),
locs());
__ Bind(&done);
}

View file

@ -239,6 +239,7 @@ class EmbeddedArray<T, 0> {
M(Constant) \
M(CheckEitherNonSmi) \
M(UnboxedDoubleBinaryOp) \
M(MathSqrt) \
M(UnboxDouble) \
M(BoxDouble) \
M(CheckArrayBound) \
@ -436,6 +437,7 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
// Classes that set deopt_id_.
friend class UnboxDoubleInstr;
friend class UnboxedDoubleBinaryOpInstr;
friend class MathSqrtInstr;
friend class CheckClassInstr;
friend class CheckSmiInstr;
friend class CheckArrayBoundInstr;
@ -1984,8 +1986,7 @@ class StaticCallInstr : public TemplateDefinition<0> {
: token_pos_(token_pos),
function_(function),
argument_names_(argument_names),
arguments_(arguments),
recognized_(MethodRecognizer::kUnknown) {
arguments_(arguments) {
ASSERT(function.IsZoneHandle());
ASSERT(argument_names.IsZoneHandle());
}
@ -2003,9 +2004,6 @@ class StaticCallInstr : public TemplateDefinition<0> {
return (*arguments_)[index];
}
MethodRecognizer::Kind recognized() const { return recognized_; }
void set_recognized(MethodRecognizer::Kind kind) { recognized_ = kind; }
virtual void PrintOperandsTo(BufferFormatter* f) const;
virtual bool CanDeoptimize() const { return true; }
@ -2016,7 +2014,6 @@ class StaticCallInstr : public TemplateDefinition<0> {
const Function& function_;
const Array& argument_names_;
ZoneGrowableArray<PushArgumentInstr*>* arguments_;
MethodRecognizer::Kind recognized_;
DISALLOW_COPY_AND_ASSIGN(StaticCallInstr);
};
@ -2854,6 +2851,49 @@ class UnboxDoubleInstr : public TemplateDefinition<1> {
};
class MathSqrtInstr : public TemplateDefinition<1> {
public:
MathSqrtInstr(Value* value, StaticCallInstr* instance_call) {
ASSERT(value != NULL);
inputs_[0] = value;
deopt_id_ = instance_call->deopt_id();
}
Value* value() const { return inputs_[0]; }
virtual bool CanDeoptimize() const { return false; }
virtual bool HasSideEffect() const { return false; }
virtual bool AttributesEqual(Definition* other) const {
return true;
}
// The output is not an instance but when it is boxed it becomes double.
virtual intptr_t ResultCid() const { return kDoubleCid; }
virtual Representation representation() const {
return kUnboxedDouble;
}
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
return kUnboxedDouble;
}
virtual intptr_t DeoptimizationTarget() const {
// Direct access since this instuction cannot deoptimize, and the deopt-id
// was inherited from another instuction that could deoptimize.
return deopt_id_;
}
DECLARE_INSTRUCTION(MathSqrt)
virtual RawAbstractType* CompileType() const;
private:
DISALLOW_COPY_AND_ASSIGN(MathSqrtInstr);
};
class UnboxedDoubleBinaryOpInstr : public TemplateDefinition<2> {
public:
UnboxedDoubleBinaryOpInstr(Token::Kind op_kind,

View file

@ -1979,6 +1979,22 @@ void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresXmmRegister());
summary->set_out(Location::RequiresXmmRegister());
return summary;
}
void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ sqrtsd(locs()->out().xmm_reg(), locs()->in(0).xmm_reg());
}
LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;

View file

@ -2006,6 +2006,22 @@ void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* summary =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresXmmRegister());
summary->set_out(Location::RequiresXmmRegister());
return summary;
}
void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ sqrtsd(locs()->out().xmm_reg(), locs()->in(0).xmm_reg());
}
LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;