Revision: 7691
Author: [email protected]
Date: Wed Apr 27 04:41:42 2011
Log: 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
http://code.google.com/p/v8/source/detail?r=7691
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.h
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Apr 26 08:22:44 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Apr 27 04:41:42 2011
@@ -150,7 +150,7 @@
}
-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::AddInstruction(LInstruction* instr, HBasicBlock* block) {
- LGap* gap = new LGap(block);
+ LInstructionGap* gap = new LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap);
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue Apr 26 08:22:44 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Apr 27 04:41:42 2011
@@ -93,7 +93,6 @@
V(ExternalArrayLength) \
V(FixedArrayLength) \
V(FunctionLiteral) \
- V(Gap) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
@@ -106,6 +105,7 @@
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
V(IsNull) \
@@ -172,18 +172,14 @@
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 void CompileToNative(LCodeGen* generator); \
- virtual const char* Mnemonic() const { return mnemonic; } \
- DECLARE_INSTRUCTION(type)
+#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_HYDROGEN_ACCESSOR(type) \
@@ -207,10 +203,25 @@
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 @@
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 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 @@
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 @@
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 @@
inputs_[1] = right;
}
+ virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
@@ -2224,7 +2249,6 @@
};
#undef DECLARE_HYDROGEN_ACCESSOR
-#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Apr 26
08:22:44 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Apr 27
04:41:42 2011
@@ -739,7 +739,7 @@
}
__ bind(label->label());
current_block_ = label->block_id();
- LCodeGen::DoGap(label);
+ DoGap(label);
}
@@ -763,6 +763,11 @@
safepoints_.SetPcAfterGap(pc);
}
}
+
+
+void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
+ DoGap(instr);
+}
void LCodeGen::DoParameter(LParameter* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Fri Apr 15
00:58:22 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Wed Apr 27
04:41:42 2011
@@ -115,6 +115,7 @@
// Parallel move support.
void DoParallelMove(LParallelMove* move);
+ void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation*
translation);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Apr 26
08:22:44 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Apr 27
04:41:42 2011
@@ -689,7 +689,7 @@
}
__ bind(label->label());
current_block_ = label->block_id();
- LCodeGen::DoGap(label);
+ DoGap(label);
}
@@ -713,6 +713,11 @@
safepoints_.SetPcAfterGap(pc);
}
}
+
+
+void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
+ DoGap(instr);
+}
void LCodeGen::DoParameter(LParameter* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Fri Apr 15
00:58:22 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Wed Apr 27
04:41:42 2011
@@ -105,6 +105,7 @@
// Parallel move support.
void DoParallelMove(LParallelMove* move);
+ void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation*
translation);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Apr 26 08:22:44
2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Apr 27 04:41:42
2011
@@ -449,7 +449,7 @@
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);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Apr 26 08:22:44 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Apr 27 04:41:42 2011
@@ -39,13 +39,6 @@
// 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 @@
V(ExternalArrayLength) \
V(FixedArrayLength) \
V(FunctionLiteral) \
- V(Gap) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
@@ -107,6 +99,7 @@
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
V(IsNull) \
@@ -173,18 +166,14 @@
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 void CompileToNative(LCodeGen* generator); \
- virtual const char* Mnemonic() const { return mnemonic; } \
- DECLARE_INSTRUCTION(type)
+#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_HYDROGEN_ACCESSOR(type) \
@@ -208,10 +197,25 @@
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 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 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 @@
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 @@
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 @@
inputs_[1] = right;
}
+ virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
@@ -2283,7 +2300,6 @@
};
#undef DECLARE_HYDROGEN_ACCESSOR
-#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Apr 26
08:22:44 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Apr 27
04:41:42 2011
@@ -690,7 +690,7 @@
}
__ bind(label->label());
current_block_ = label->block_id();
- LCodeGen::DoGap(label);
+ DoGap(label);
}
@@ -714,6 +714,11 @@
safepoints_.SetPcAfterGap(pc);
}
}
+
+
+void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
+ DoGap(instr);
+}
void LCodeGen::DoParameter(LParameter* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Fri Apr 15
00:58:22 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Wed Apr 27
04:41:42 2011
@@ -102,6 +102,7 @@
// Parallel move support.
void DoParallelMove(LParallelMove* move);
+ void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation*
translation);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Apr 26 08:22:44 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Apr 27 04:41:42 2011
@@ -448,7 +448,7 @@
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);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Apr 26 08:22:44 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Apr 27 04:41:42 2011
@@ -93,7 +93,6 @@
V(ExternalArrayLength) \
V(FixedArrayLength) \
V(FunctionLiteral) \
- V(Gap) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
@@ -106,6 +105,7 @@
V(InstanceOf) \
V(InstanceOfAndBranch) \
V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
V(IsNull) \
@@ -172,18 +172,14 @@
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 void CompileToNative(LCodeGen* generator); \
- virtual const char* Mnemonic() const { return mnemonic; } \
- DECLARE_INSTRUCTION(type)
+#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_HYDROGEN_ACCESSOR(type) \
@@ -208,10 +204,25 @@
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 @@
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 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 @@
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 @@
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 @@
inputs_[1] = right;
}
+ virtual Opcode opcode() const { return LInstruction::kArithmeticT; }
virtual void CompileToNative(LCodeGen* generator);
virtual const char* Mnemonic() const;
@@ -2206,7 +2231,6 @@
};
#undef DECLARE_HYDROGEN_ACCESSOR
-#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION
} } // namespace v8::int
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev