Commit 670df506 authored by titzer@chromium.org's avatar titzer@chromium.org

Implement representation selection as part of SimplifiedLowering. Representation selection also

requires inserting explicit representation change nodes to be inserted in the graph. Such nodes
are pure, but also need to be lowered to machine operators. They need to be scheduled first, to
determine the control input for any branches inside.

This CL requires extensive testing. More tests to follow.

R=rossberg@chromium.org
BUG=

Review URL: https://codereview.chromium.org/425003004

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23026 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fc87e1d4
......@@ -16,8 +16,12 @@ class LoweringBuilder::NodeVisitor : public NullNodeVisitor {
explicit NodeVisitor(LoweringBuilder* lowering) : lowering_(lowering) {}
GenericGraphVisit::Control Post(Node* node) {
SourcePositionTable::Scope pos(lowering_->source_positions_, node);
lowering_->Lower(node);
if (lowering_->source_positions_ != NULL) {
SourcePositionTable::Scope pos(lowering_->source_positions_, node);
lowering_->Lower(node);
} else {
lowering_->Lower(node);
}
return GenericGraphVisit::CONTINUE;
}
......
......@@ -40,7 +40,6 @@ class NodeProperties {
static inline int GetContextIndex(Node* node);
private:
static inline int FirstValueIndex(Node* node);
static inline int FirstEffectIndex(Node* node);
static inline int FirstControlIndex(Node* node);
......
......@@ -231,7 +231,7 @@ Schedule* Pipeline::ComputeSchedule(Graph* graph) {
Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
Graph* graph,
Schedule* schedule) {
CHECK(SupportedTarget());
CHECK(SupportedBackend());
if (schedule == NULL) {
VerifyAndPrintGraph(graph, "Machine");
schedule = ComputeSchedule(graph);
......@@ -257,7 +257,7 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph,
DCHECK_NOT_NULL(graph);
DCHECK_NOT_NULL(linkage);
DCHECK_NOT_NULL(schedule);
DCHECK(SupportedTarget());
CHECK(SupportedBackend());
InstructionSequence sequence(linkage, graph, schedule);
......
......@@ -36,14 +36,28 @@ enum RepType {
tAny = 1 << 11
};
#define REP_TYPE_STRLEN 24
typedef uint16_t RepTypeUnion;
inline void RenderRepTypeUnion(char* buf, RepTypeUnion info) {
base::OS::SNPrintF(buf, REP_TYPE_STRLEN, "{%s%s%s%s%s %s%s%s%s%s%s%s}",
(info & rBit) ? "k" : " ", (info & rWord32) ? "w" : " ",
(info & rWord64) ? "q" : " ",
(info & rFloat64) ? "f" : " ",
(info & rTagged) ? "t" : " ", (info & tBool) ? "Z" : " ",
(info & tInt32) ? "I" : " ", (info & tUint32) ? "U" : " ",
(info & tInt64) ? "L" : " ", (info & tUint64) ? "J" : " ",
(info & tNumber) ? "N" : " ", (info & tAny) ? "*" : " ");
}
const RepTypeUnion rMask = rBit | rWord32 | rWord64 | rFloat64 | rTagged;
const RepTypeUnion tMask =
tBool | tInt32 | tUint32 | tInt64 | tUint64 | tNumber | tAny;
const RepType rPtr = kPointerSize == 4 ? rWord32 : rWord64;
// Contains logic related to changing the representation of values for constants
// and other nodes, as well as lowering Simplified->Machine operators.
// Eagerly folds any representation changes for constants.
......@@ -344,10 +358,24 @@ class RepresentationChanger {
return static_cast<RepType>(tElement | rElement);
}
RepType TypeForBasePointer(Node* node) {
Type* upper = NodeProperties::GetBounds(node).upper;
if (upper->Is(Type::UntaggedPtr())) return rPtr;
return static_cast<RepType>(tAny | rTagged);
RepType TypeForBasePointer(const FieldAccess& access) {
if (access.tag() != 0) return static_cast<RepType>(tAny | rTagged);
return kPointerSize == 8 ? rWord64 : rWord32;
}
RepType TypeForBasePointer(const ElementAccess& access) {
if (access.tag() != 0) return static_cast<RepType>(tAny | rTagged);
return kPointerSize == 8 ? rWord64 : rWord32;
}
RepType TypeFromUpperBound(Type* type) {
if (type->Is(Type::None()))
return tAny; // TODO(titzer): should be an error
if (type->Is(Type::Signed32())) return tInt32;
if (type->Is(Type::Unsigned32())) return tUint32;
if (type->Is(Type::Number())) return tNumber;
if (type->Is(Type::Boolean())) return tBool;
return tAny;
}
private:
......@@ -364,7 +392,14 @@ class RepresentationChanger {
Node* TypeError(Node* node, RepTypeUnion output_type, RepTypeUnion use) {
type_error_ = true;
if (!testing_type_errors_) {
UNREACHABLE(); // TODO(titzer): report nicer type error
char buf1[REP_TYPE_STRLEN];
char buf2[REP_TYPE_STRLEN];
RenderRepTypeUnion(buf1, output_type);
RenderRepTypeUnion(buf2, use);
V8_Fatal(__FILE__, __LINE__,
"RepresentationChangerError: node #%d:%s of rep"
"%s cannot be changed to rep%s",
node->id(), node->op()->mnemonic(), buf1, buf2);
}
return node;
}
......
This diff is collapsed.
......@@ -25,21 +25,16 @@ class SimplifiedLowering : public LoweringBuilder {
machine_(jsgraph->zone()) {}
virtual ~SimplifiedLowering() {}
void LowerAllNodes();
virtual void Lower(Node* node);
void LowerChange(Node* node, Node* effect, Node* control);
// TODO(titzer): These are exposed for direct testing. Use a friend class.
void DoChangeTaggedToUI32(Node* node, Node* effect, Node* control,
bool is_signed);
void DoChangeUI32ToTagged(Node* node, Node* effect, Node* control,
bool is_signed);
void DoChangeTaggedToFloat64(Node* node, Node* effect, Node* control);
void DoChangeFloat64ToTagged(Node* node, Node* effect, Node* control);
void DoChangeBoolToBit(Node* node, Node* effect, Node* control);
void DoChangeBitToBool(Node* node, Node* effect, Node* control);
void DoLoadField(Node* node, Node* effect, Node* control);
void DoStoreField(Node* node, Node* effect, Node* control);
void DoLoadElement(Node* node, Node* effect, Node* control);
void DoStoreElement(Node* node, Node* effect, Node* control);
void DoLoadField(Node* node);
void DoStoreField(Node* node);
void DoLoadElement(Node* node);
void DoStoreElement(Node* node);
private:
JSGraph* jsgraph_;
......@@ -49,9 +44,19 @@ class SimplifiedLowering : public LoweringBuilder {
Node* IsTagged(Node* node);
Node* Untag(Node* node);
Node* OffsetMinusTagConstant(int32_t offset);
Node* ComputeIndex(const ElementAccess& access, Node* index);
void DoChangeTaggedToUI32(Node* node, Node* effect, Node* control,
bool is_signed);
void DoChangeUI32ToTagged(Node* node, Node* effect, Node* control,
bool is_signed);
void DoChangeTaggedToFloat64(Node* node, Node* effect, Node* control);
void DoChangeFloat64ToTagged(Node* node, Node* effect, Node* control);
void DoChangeBoolToBit(Node* node, Node* effect, Node* control);
void DoChangeBitToBool(Node* node, Node* effect, Node* control);
friend class RepresentationSelector;
Zone* zone() { return jsgraph_->zone(); }
JSGraph* jsgraph() { return jsgraph_; }
Graph* graph() { return jsgraph()->graph(); }
......
......@@ -106,6 +106,7 @@ struct ReturnValueTraits<double> {
UNREACHABLE();
return 0.0;
}
static MachineRepresentation Representation() { return kMachineFloat64; }
};
......
......@@ -41,6 +41,8 @@ class MachineCallHelper : public CallHelper {
Node* Parameter(int offset);
void GenerateCode() { Generate(); }
protected:
virtual byte* Generate();
virtual void VerifyParameters(int parameter_count,
......@@ -71,7 +73,7 @@ class GraphAndBuilders {
protected:
// Prefixed with main_ to avoid naiming conflicts.
Graph* const main_graph_;
Graph* main_graph_;
CommonOperatorBuilder main_common_;
MachineOperatorBuilder main_machine_;
SimplifiedOperatorBuilder main_simplified_;
......
......@@ -108,7 +108,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
this->start(), this->start());
Node* end = this->graph()->NewNode(this->common()->End(), ret);
this->graph()->SetEnd(end);
this->lowering.Lower(change);
this->lowering.LowerChange(change, this->start(), this->start());
Verifier::Run(this->graph());
}
......@@ -124,7 +124,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
this->common()->Return(), this->Int32Constant(0), store, this->start());
Node* end = this->graph()->NewNode(this->common()->End(), ret);
this->graph()->SetEnd(end);
this->lowering.Lower(change);
this->lowering.LowerChange(change, this->start(), this->start());
Verifier::Run(this->graph());
}
......@@ -139,7 +139,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
this->start(), this->start());
Node* end = this->graph()->NewNode(this->common()->End(), ret);
this->graph()->SetEnd(end);
this->lowering.Lower(change);
this->lowering.LowerChange(change, this->start(), this->start());
Verifier::Run(this->graph());
}
......
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