mirror of
https://github.com/dart-lang/sdk
synced 2024-09-20 03:31:28 +00:00
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:
parent
0163d32763
commit
5f37ef55a5
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue