Refactor lithium classes to reduce the number of virtual functions.

This reduces the binary size by making the Is* type-test functions non-virtual.

I had to change Gap and Label instructions to have a common abstract superclass because both act as gap-instructions for the register allocator.
Review URL: http://codereview.chromium.org/6880204

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7691 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 038fa0b4
......@@ -150,7 +150,7 @@ bool LGap::IsRedundant() const {
}
void LGap::PrintDataTo(StringStream* stream) const {
void LGap::PrintDataTo(StringStream* stream) {
for (int i = 0; i < 4; i++) {
stream->Add("(");
if (parallel_moves_[i] != NULL) {
......@@ -455,7 +455,7 @@ void LChunk::MarkEmptyBlocks() {
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LGap* gap = new LGap(block);
LInstructionGap* gap = new LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap);
......
......@@ -93,7 +93,6 @@ class LCodeGen;
V(ExternalArrayLength) \
V(FixedArrayLength) \
V(FunctionLiteral) \
V(Gap) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
......@@ -106,6 +105,7 @@ class LCodeGen;
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
V(IsNull) \
......@@ -172,20 +172,16 @@ class LCodeGen;
V(ValueOf)
#define DECLARE_INSTRUCTION(type) \
virtual bool Is##type() const { return true; } \
static L##type* cast(LInstruction* instr) { \
ASSERT(instr->Is##type()); \
return reinterpret_cast<L##type*>(instr); \
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual Opcode opcode() const { return LInstruction::k##type; } \
virtual void CompileToNative(LCodeGen* generator); \
virtual const char* Mnemonic() const { return mnemonic; } \
static L##type* cast(LInstruction* instr) { \
ASSERT(instr->Is##type()); \
return reinterpret_cast<L##type*>(instr); \
}
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual void CompileToNative(LCodeGen* generator); \
virtual const char* Mnemonic() const { return mnemonic; } \
DECLARE_INSTRUCTION(type)
#define DECLARE_HYDROGEN_ACCESSOR(type) \
H##type* hydrogen() const { \
return H##type::cast(hydrogen_value()); \
......@@ -207,10 +203,25 @@ class LInstruction: public ZoneObject {
virtual void PrintDataTo(StringStream* stream) = 0;
virtual void PrintOutputOperandTo(StringStream* stream) = 0;
// Declare virtual type testers.
#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
enum Opcode {
// Declare a unique enum value for each instruction.
#define DECLARE_OPCODE(type) k##type,
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
kNumberOfInstructions
#undef DECLARE_OPCODE
};
virtual Opcode opcode() const = 0;
// Declare non-virtual type testers for all leaf IR classes.
#define DECLARE_PREDICATE(type) \
bool Is##type() const { return opcode() == k##type; }
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
#undef DECLARE_PREDICATE
// Declare virtual predicates for instructions that don't have
// an opcode.
virtual bool IsGap() const { return false; }
virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
......@@ -337,8 +348,13 @@ class LGap: public LTemplateInstruction<0, 0, 0> {
parallel_moves_[AFTER] = NULL;
}
DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
virtual void PrintDataTo(StringStream* stream) const;
// Can't use the DECLARE-macro here because of sub-classes.
virtual bool IsGap() const { return true; }
virtual void PrintDataTo(StringStream* stream);
static LGap* cast(LInstruction* instr) {
ASSERT(instr->IsGap());
return reinterpret_cast<LGap*>(instr);
}
bool IsRedundant() const;
......@@ -368,6 +384,14 @@ class LGap: public LTemplateInstruction<0, 0, 0> {
};
class LInstructionGap: public LGap {
public:
explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
};
class LGoto: public LTemplateInstruction<0, 0, 0> {
public:
LGoto(int block_id, bool include_stack_check = false)
......@@ -456,7 +480,6 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
template<int I, int T>
class LControlInstruction: public LTemplateInstruction<0, I, T> {
public:
DECLARE_INSTRUCTION(ControlInstruction)
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
......@@ -1107,6 +1130,7 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
Token::Value op() const { return op_; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -1123,6 +1147,7 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -2224,7 +2249,6 @@ class LChunkBuilder BASE_EMBEDDED {
};
#undef DECLARE_HYDROGEN_ACCESSOR
#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION
} } // namespace v8::internal
......
......@@ -739,7 +739,7 @@ void LCodeGen::DoLabel(LLabel* label) {
}
__ bind(label->label());
current_block_ = label->block_id();
LCodeGen::DoGap(label);
DoGap(label);
}
......@@ -765,6 +765,11 @@ void LCodeGen::DoGap(LGap* gap) {
}
void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
DoGap(instr);
}
void LCodeGen::DoParameter(LParameter* instr) {
// Nothing to do.
}
......
......@@ -115,6 +115,7 @@ class LCodeGen BASE_EMBEDDED {
// Parallel move support.
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation* translation);
......
......@@ -689,7 +689,7 @@ void LCodeGen::DoLabel(LLabel* label) {
}
__ bind(label->label());
current_block_ = label->block_id();
LCodeGen::DoGap(label);
DoGap(label);
}
......@@ -715,6 +715,11 @@ void LCodeGen::DoGap(LGap* gap) {
}
void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
DoGap(instr);
}
void LCodeGen::DoParameter(LParameter* instr) {
// Nothing to do.
}
......
......@@ -105,6 +105,7 @@ class LCodeGen BASE_EMBEDDED {
// Parallel move support.
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation* translation);
......
......@@ -449,7 +449,7 @@ void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LGap* gap = new LGap(block);
LInstructionGap* gap = new LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap);
......
......@@ -39,13 +39,6 @@ namespace internal {
// Forward declarations.
class LCodeGen;
#define LITHIUM_ALL_INSTRUCTION_LIST(V) \
V(ControlInstruction) \
V(Call) \
LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
V(AccessArgumentsAt) \
V(AddI) \
......@@ -94,7 +87,6 @@ class LCodeGen;
V(ExternalArrayLength) \
V(FixedArrayLength) \
V(FunctionLiteral) \
V(Gap) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
......@@ -107,6 +99,7 @@ class LCodeGen;
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
V(IsNull) \
......@@ -173,20 +166,16 @@ class LCodeGen;
V(ValueOf)
#define DECLARE_INSTRUCTION(type) \
virtual bool Is##type() const { return true; } \
static L##type* cast(LInstruction* instr) { \
ASSERT(instr->Is##type()); \
return reinterpret_cast<L##type*>(instr); \
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual Opcode opcode() const { return LInstruction::k##type; } \
virtual void CompileToNative(LCodeGen* generator); \
virtual const char* Mnemonic() const { return mnemonic; } \
static L##type* cast(LInstruction* instr) { \
ASSERT(instr->Is##type()); \
return reinterpret_cast<L##type*>(instr); \
}
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual void CompileToNative(LCodeGen* generator); \
virtual const char* Mnemonic() const { return mnemonic; } \
DECLARE_INSTRUCTION(type)
#define DECLARE_HYDROGEN_ACCESSOR(type) \
H##type* hydrogen() const { \
return H##type::cast(hydrogen_value()); \
......@@ -208,10 +197,25 @@ class LInstruction: public ZoneObject {
virtual void PrintDataTo(StringStream* stream) = 0;
virtual void PrintOutputOperandTo(StringStream* stream) = 0;
// Declare virtual type testers.
#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
enum Opcode {
// Declare a unique enum value for each instruction.
#define DECLARE_OPCODE(type) k##type,
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
kNumberOfInstructions
#undef DECLARE_OPCODE
};
virtual Opcode opcode() const = 0;
// Declare non-virtual type testers for all leaf IR classes.
#define DECLARE_PREDICATE(type) \
bool Is##type() const { return opcode() == k##type; }
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
#undef DECLARE_PREDICATE
// Declare virtual predicates for instructions that don't have
// an opcode.
virtual bool IsGap() const { return false; }
virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
......@@ -331,16 +335,20 @@ class LTemplateInstruction: public LInstruction {
class LGap: public LTemplateInstruction<0, 0, 0> {
public:
explicit LGap(HBasicBlock* block)
: block_(block) {
explicit LGap(HBasicBlock* block) : block_(block) {
parallel_moves_[BEFORE] = NULL;
parallel_moves_[START] = NULL;
parallel_moves_[END] = NULL;
parallel_moves_[AFTER] = NULL;
}
DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
// Can't use the DECLARE-macro here because of sub-classes.
virtual bool IsGap() const { return true; }
virtual void PrintDataTo(StringStream* stream);
static LGap* cast(LInstruction* instr) {
ASSERT(instr->IsGap());
return reinterpret_cast<LGap*>(instr);
}
bool IsRedundant() const;
......@@ -370,6 +378,14 @@ class LGap: public LTemplateInstruction<0, 0, 0> {
};
class LInstructionGap: public LGap {
public:
explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
};
class LGoto: public LTemplateInstruction<0, 0, 0> {
public:
LGoto(int block_id, bool include_stack_check = false)
......@@ -464,7 +480,6 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
template<int I, int T>
class LControlInstruction: public LTemplateInstruction<0, I, T> {
public:
DECLARE_INSTRUCTION(ControlInstruction)
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
......@@ -1134,6 +1149,7 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
Token::Value op() const { return op_; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -1150,6 +1166,7 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -2283,7 +2300,6 @@ class LChunkBuilder BASE_EMBEDDED {
};
#undef DECLARE_HYDROGEN_ACCESSOR
#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION
} } // namespace v8::internal
......
......@@ -690,7 +690,7 @@ void LCodeGen::DoLabel(LLabel* label) {
}
__ bind(label->label());
current_block_ = label->block_id();
LCodeGen::DoGap(label);
DoGap(label);
}
......@@ -716,6 +716,11 @@ void LCodeGen::DoGap(LGap* gap) {
}
void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
DoGap(instr);
}
void LCodeGen::DoParameter(LParameter* instr) {
// Nothing to do.
}
......
......@@ -102,6 +102,7 @@ class LCodeGen BASE_EMBEDDED {
// Parallel move support.
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation* translation);
......
......@@ -448,7 +448,7 @@ void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LGap* gap = new LGap(block);
LInstructionGap* gap = new LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap);
......
......@@ -93,7 +93,6 @@ class LCodeGen;
V(ExternalArrayLength) \
V(FixedArrayLength) \
V(FunctionLiteral) \
V(Gap) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
......@@ -106,6 +105,7 @@ class LCodeGen;
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
V(IsNull) \
......@@ -172,20 +172,16 @@ class LCodeGen;
V(ValueOf)
#define DECLARE_INSTRUCTION(type) \
virtual bool Is##type() const { return true; } \
static L##type* cast(LInstruction* instr) { \
ASSERT(instr->Is##type()); \
return reinterpret_cast<L##type*>(instr); \
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual Opcode opcode() const { return LInstruction::k##type; } \
virtual void CompileToNative(LCodeGen* generator); \
virtual const char* Mnemonic() const { return mnemonic; } \
static L##type* cast(LInstruction* instr) { \
ASSERT(instr->Is##type()); \
return reinterpret_cast<L##type*>(instr); \
}
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual void CompileToNative(LCodeGen* generator); \
virtual const char* Mnemonic() const { return mnemonic; } \
DECLARE_INSTRUCTION(type)
#define DECLARE_HYDROGEN_ACCESSOR(type) \
H##type* hydrogen() const { \
return H##type::cast(hydrogen_value()); \
......@@ -208,10 +204,25 @@ class LInstruction: public ZoneObject {
virtual void PrintDataTo(StringStream* stream) = 0;
virtual void PrintOutputOperandTo(StringStream* stream) = 0;
// Declare virtual type testers.
#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
enum Opcode {
// Declare a unique enum value for each instruction.
#define DECLARE_OPCODE(type) k##type,
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
kNumberOfInstructions
#undef DECLARE_OPCODE
};
virtual Opcode opcode() const = 0;
// Declare non-virtual type testers for all leaf IR classes.
#define DECLARE_PREDICATE(type) \
bool Is##type() const { return opcode() == k##type; }
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
#undef DECLARE_PREDICATE
// Declare virtual predicates for instructions that don't have
// an opcode.
virtual bool IsGap() const { return false; }
virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
......@@ -338,8 +349,13 @@ class LGap: public LTemplateInstruction<0, 0, 0> {
parallel_moves_[AFTER] = NULL;
}
DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
// Can't use the DECLARE-macro here because of sub-classes.
virtual bool IsGap() const { return true; }
virtual void PrintDataTo(StringStream* stream);
static LGap* cast(LInstruction* instr) {
ASSERT(instr->IsGap());
return reinterpret_cast<LGap*>(instr);
}
bool IsRedundant() const;
......@@ -369,6 +385,14 @@ class LGap: public LTemplateInstruction<0, 0, 0> {
};
class LInstructionGap: public LGap {
public:
explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
};
class LGoto: public LTemplateInstruction<0, 0, 0> {
public:
LGoto(int block_id, bool include_stack_check = false)
......@@ -457,7 +481,6 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
template<int I, int T>
class LControlInstruction: public LTemplateInstruction<0, I, T> {
public:
DECLARE_INSTRUCTION(ControlInstruction)
virtual bool IsControl() const { return true; }
int true_block_id() const { return true_block_id_; }
......@@ -1107,6 +1130,7 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
Token::Value op() const { return op_; }
virtual Opcode opcode() const { return LInstruction::kArithmeticD; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -1123,6 +1147,7 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
inputs_[1] = right;
}
virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
......@@ -2206,7 +2231,6 @@ class LChunkBuilder BASE_EMBEDDED {
};
#undef DECLARE_HYDROGEN_ACCESSOR
#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION
} } // namespace v8::int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment