Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
      6 #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
      7 
      8 #include "src/v8.h"
      9 
     10 #include "src/compiler/common-operator.h"
     11 #include "src/compiler/graph-builder.h"
     12 #include "src/compiler/linkage.h"
     13 #include "src/compiler/machine-operator.h"
     14 #include "src/compiler/node.h"
     15 #include "src/compiler/operator.h"
     16 
     17 
     18 namespace v8 {
     19 namespace internal {
     20 namespace compiler {
     21 
     22 class BasicBlock;
     23 class Schedule;
     24 
     25 
     26 class RawMachineAssembler : public GraphBuilder {
     27  public:
     28   class Label {
     29    public:
     30     Label() : block_(NULL), used_(false), bound_(false) {}
     31     ~Label() { DCHECK(bound_ || !used_); }
     32 
     33     BasicBlock* block() { return block_; }
     34 
     35    private:
     36     // Private constructor for exit label.
     37     explicit Label(BasicBlock* block)
     38         : block_(block), used_(false), bound_(false) {}
     39 
     40     BasicBlock* block_;
     41     bool used_;
     42     bool bound_;
     43     friend class RawMachineAssembler;
     44     DISALLOW_COPY_AND_ASSIGN(Label);
     45   };
     46 
     47   RawMachineAssembler(Graph* graph, MachineSignature* machine_sig,
     48                       MachineType word = kMachPtr);
     49   virtual ~RawMachineAssembler() {}
     50 
     51   Isolate* isolate() const { return zone()->isolate(); }
     52   Zone* zone() const { return graph()->zone(); }
     53   MachineOperatorBuilder* machine() { return &machine_; }
     54   CommonOperatorBuilder* common() { return &common_; }
     55   CallDescriptor* call_descriptor() const { return call_descriptor_; }
     56   size_t parameter_count() const { return machine_sig_->parameter_count(); }
     57   MachineSignature* machine_sig() const { return machine_sig_; }
     58 
     59   Node* UndefinedConstant() {
     60     Unique<Object> unique = Unique<Object>::CreateImmovable(
     61         isolate()->factory()->undefined_value());
     62     return NewNode(common()->HeapConstant(unique));
     63   }
     64 
     65   // Constants.
     66   Node* PointerConstant(void* value) {
     67     return IntPtrConstant(reinterpret_cast<intptr_t>(value));
     68   }
     69   Node* IntPtrConstant(intptr_t value) {
     70     // TODO(dcarney): mark generated code as unserializable if value != 0.
     71     return kPointerSize == 8 ? Int64Constant(value)
     72                              : Int32Constant(static_cast<int>(value));
     73   }
     74   Node* Int32Constant(int32_t value) {
     75     return NewNode(common()->Int32Constant(value));
     76   }
     77   Node* Int64Constant(int64_t value) {
     78     return NewNode(common()->Int64Constant(value));
     79   }
     80   Node* NumberConstant(double value) {
     81     return NewNode(common()->NumberConstant(value));
     82   }
     83   Node* Float64Constant(double value) {
     84     return NewNode(common()->Float64Constant(value));
     85   }
     86   Node* HeapConstant(Handle<Object> object) {
     87     Unique<Object> val = Unique<Object>::CreateUninitialized(object);
     88     return NewNode(common()->HeapConstant(val));
     89   }
     90 
     91   Node* Projection(int index, Node* a) {
     92     return NewNode(common()->Projection(index), a);
     93   }
     94 
     95   // Memory Operations.
     96   Node* Load(MachineType rep, Node* base) {
     97     return Load(rep, base, Int32Constant(0));
     98   }
     99   Node* Load(MachineType rep, Node* base, Node* index) {
    100     return NewNode(machine()->Load(rep), base, index);
    101   }
    102   void Store(MachineType rep, Node* base, Node* value) {
    103     Store(rep, base, Int32Constant(0), value);
    104   }
    105   void Store(MachineType rep, Node* base, Node* index, Node* value) {
    106     NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
    107             index, value);
    108   }
    109   // Arithmetic Operations.
    110   Node* WordAnd(Node* a, Node* b) {
    111     return NewNode(machine()->WordAnd(), a, b);
    112   }
    113   Node* WordOr(Node* a, Node* b) { return NewNode(machine()->WordOr(), a, b); }
    114   Node* WordXor(Node* a, Node* b) {
    115     return NewNode(machine()->WordXor(), a, b);
    116   }
    117   Node* WordShl(Node* a, Node* b) {
    118     return NewNode(machine()->WordShl(), a, b);
    119   }
    120   Node* WordShr(Node* a, Node* b) {
    121     return NewNode(machine()->WordShr(), a, b);
    122   }
    123   Node* WordSar(Node* a, Node* b) {
    124     return NewNode(machine()->WordSar(), a, b);
    125   }
    126   Node* WordRor(Node* a, Node* b) {
    127     return NewNode(machine()->WordRor(), a, b);
    128   }
    129   Node* WordEqual(Node* a, Node* b) {
    130     return NewNode(machine()->WordEqual(), a, b);
    131   }
    132   Node* WordNotEqual(Node* a, Node* b) {
    133     return WordBinaryNot(WordEqual(a, b));
    134   }
    135   Node* WordNot(Node* a) {
    136     if (machine()->Is32()) {
    137       return Word32Not(a);
    138     } else {
    139       return Word64Not(a);
    140     }
    141   }
    142   Node* WordBinaryNot(Node* a) {
    143     if (machine()->Is32()) {
    144       return Word32BinaryNot(a);
    145     } else {
    146       return Word64BinaryNot(a);
    147     }
    148   }
    149 
    150   Node* Word32And(Node* a, Node* b) {
    151     return NewNode(machine()->Word32And(), a, b);
    152   }
    153   Node* Word32Or(Node* a, Node* b) {
    154     return NewNode(machine()->Word32Or(), a, b);
    155   }
    156   Node* Word32Xor(Node* a, Node* b) {
    157     return NewNode(machine()->Word32Xor(), a, b);
    158   }
    159   Node* Word32Shl(Node* a, Node* b) {
    160     return NewNode(machine()->Word32Shl(), a, b);
    161   }
    162   Node* Word32Shr(Node* a, Node* b) {
    163     return NewNode(machine()->Word32Shr(), a, b);
    164   }
    165   Node* Word32Sar(Node* a, Node* b) {
    166     return NewNode(machine()->Word32Sar(), a, b);
    167   }
    168   Node* Word32Ror(Node* a, Node* b) {
    169     return NewNode(machine()->Word32Ror(), a, b);
    170   }
    171   Node* Word32Equal(Node* a, Node* b) {
    172     return NewNode(machine()->Word32Equal(), a, b);
    173   }
    174   Node* Word32NotEqual(Node* a, Node* b) {
    175     return Word32BinaryNot(Word32Equal(a, b));
    176   }
    177   Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
    178   Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
    179 
    180   Node* Word64And(Node* a, Node* b) {
    181     return NewNode(machine()->Word64And(), a, b);
    182   }
    183   Node* Word64Or(Node* a, Node* b) {
    184     return NewNode(machine()->Word64Or(), a, b);
    185   }
    186   Node* Word64Xor(Node* a, Node* b) {
    187     return NewNode(machine()->Word64Xor(), a, b);
    188   }
    189   Node* Word64Shl(Node* a, Node* b) {
    190     return NewNode(machine()->Word64Shl(), a, b);
    191   }
    192   Node* Word64Shr(Node* a, Node* b) {
    193     return NewNode(machine()->Word64Shr(), a, b);
    194   }
    195   Node* Word64Sar(Node* a, Node* b) {
    196     return NewNode(machine()->Word64Sar(), a, b);
    197   }
    198   Node* Word64Ror(Node* a, Node* b) {
    199     return NewNode(machine()->Word64Ror(), a, b);
    200   }
    201   Node* Word64Equal(Node* a, Node* b) {
    202     return NewNode(machine()->Word64Equal(), a, b);
    203   }
    204   Node* Word64NotEqual(Node* a, Node* b) {
    205     return Word64BinaryNot(Word64Equal(a, b));
    206   }
    207   Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
    208   Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); }
    209 
    210   Node* Int32Add(Node* a, Node* b) {
    211     return NewNode(machine()->Int32Add(), a, b);
    212   }
    213   Node* Int32AddWithOverflow(Node* a, Node* b) {
    214     return NewNode(machine()->Int32AddWithOverflow(), a, b);
    215   }
    216   Node* Int32Sub(Node* a, Node* b) {
    217     return NewNode(machine()->Int32Sub(), a, b);
    218   }
    219   Node* Int32SubWithOverflow(Node* a, Node* b) {
    220     return NewNode(machine()->Int32SubWithOverflow(), a, b);
    221   }
    222   Node* Int32Mul(Node* a, Node* b) {
    223     return NewNode(machine()->Int32Mul(), a, b);
    224   }
    225   Node* Int32Div(Node* a, Node* b) {
    226     return NewNode(machine()->Int32Div(), a, b);
    227   }
    228   Node* Int32UDiv(Node* a, Node* b) {
    229     return NewNode(machine()->Int32UDiv(), a, b);
    230   }
    231   Node* Int32Mod(Node* a, Node* b) {
    232     return NewNode(machine()->Int32Mod(), a, b);
    233   }
    234   Node* Int32UMod(Node* a, Node* b) {
    235     return NewNode(machine()->Int32UMod(), a, b);
    236   }
    237   Node* Int32LessThan(Node* a, Node* b) {
    238     return NewNode(machine()->Int32LessThan(), a, b);
    239   }
    240   Node* Int32LessThanOrEqual(Node* a, Node* b) {
    241     return NewNode(machine()->Int32LessThanOrEqual(), a, b);
    242   }
    243   Node* Uint32LessThan(Node* a, Node* b) {
    244     return NewNode(machine()->Uint32LessThan(), a, b);
    245   }
    246   Node* Uint32LessThanOrEqual(Node* a, Node* b) {
    247     return NewNode(machine()->Uint32LessThanOrEqual(), a, b);
    248   }
    249   Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
    250   Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
    251     return Int32LessThanOrEqual(b, a);
    252   }
    253   Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
    254 
    255   Node* Int64Add(Node* a, Node* b) {
    256     return NewNode(machine()->Int64Add(), a, b);
    257   }
    258   Node* Int64Sub(Node* a, Node* b) {
    259     return NewNode(machine()->Int64Sub(), a, b);
    260   }
    261   Node* Int64Mul(Node* a, Node* b) {
    262     return NewNode(machine()->Int64Mul(), a, b);
    263   }
    264   Node* Int64Div(Node* a, Node* b) {
    265     return NewNode(machine()->Int64Div(), a, b);
    266   }
    267   Node* Int64UDiv(Node* a, Node* b) {
    268     return NewNode(machine()->Int64UDiv(), a, b);
    269   }
    270   Node* Int64Mod(Node* a, Node* b) {
    271     return NewNode(machine()->Int64Mod(), a, b);
    272   }
    273   Node* Int64UMod(Node* a, Node* b) {
    274     return NewNode(machine()->Int64UMod(), a, b);
    275   }
    276   Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
    277   Node* Int64LessThan(Node* a, Node* b) {
    278     return NewNode(machine()->Int64LessThan(), a, b);
    279   }
    280   Node* Int64LessThanOrEqual(Node* a, Node* b) {
    281     return NewNode(machine()->Int64LessThanOrEqual(), a, b);
    282   }
    283   Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
    284   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
    285     return Int64LessThanOrEqual(b, a);
    286   }
    287 
    288   // TODO(turbofan): What is this used for?
    289   Node* ConvertIntPtrToInt32(Node* a) {
    290     return kPointerSize == 8 ? NewNode(machine()->TruncateInt64ToInt32(), a)
    291                              : a;
    292   }
    293   Node* ConvertInt32ToIntPtr(Node* a) {
    294     return kPointerSize == 8 ? NewNode(machine()->ChangeInt32ToInt64(), a) : a;
    295   }
    296 
    297 #define INTPTR_BINOP(prefix, name)                     \
    298   Node* IntPtr##name(Node* a, Node* b) {               \
    299     return kPointerSize == 8 ? prefix##64##name(a, b)  \
    300                              : prefix##32##name(a, b); \
    301   }
    302 
    303   INTPTR_BINOP(Int, Add);
    304   INTPTR_BINOP(Int, Sub);
    305   INTPTR_BINOP(Int, LessThan);
    306   INTPTR_BINOP(Int, LessThanOrEqual);
    307   INTPTR_BINOP(Word, Equal);
    308   INTPTR_BINOP(Word, NotEqual);
    309   INTPTR_BINOP(Int, GreaterThanOrEqual);
    310   INTPTR_BINOP(Int, GreaterThan);
    311 
    312 #undef INTPTR_BINOP
    313 
    314   Node* Float64Add(Node* a, Node* b) {
    315     return NewNode(machine()->Float64Add(), a, b);
    316   }
    317   Node* Float64Sub(Node* a, Node* b) {
    318     return NewNode(machine()->Float64Sub(), a, b);
    319   }
    320   Node* Float64Mul(Node* a, Node* b) {
    321     return NewNode(machine()->Float64Mul(), a, b);
    322   }
    323   Node* Float64Div(Node* a, Node* b) {
    324     return NewNode(machine()->Float64Div(), a, b);
    325   }
    326   Node* Float64Mod(Node* a, Node* b) {
    327     return NewNode(machine()->Float64Mod(), a, b);
    328   }
    329   Node* Float64Equal(Node* a, Node* b) {
    330     return NewNode(machine()->Float64Equal(), a, b);
    331   }
    332   Node* Float64NotEqual(Node* a, Node* b) {
    333     return WordBinaryNot(Float64Equal(a, b));
    334   }
    335   Node* Float64LessThan(Node* a, Node* b) {
    336     return NewNode(machine()->Float64LessThan(), a, b);
    337   }
    338   Node* Float64LessThanOrEqual(Node* a, Node* b) {
    339     return NewNode(machine()->Float64LessThanOrEqual(), a, b);
    340   }
    341   Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
    342   Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
    343     return Float64LessThanOrEqual(b, a);
    344   }
    345 
    346   // Conversions.
    347   Node* ChangeInt32ToFloat64(Node* a) {
    348     return NewNode(machine()->ChangeInt32ToFloat64(), a);
    349   }
    350   Node* ChangeUint32ToFloat64(Node* a) {
    351     return NewNode(machine()->ChangeUint32ToFloat64(), a);
    352   }
    353   Node* ChangeFloat64ToInt32(Node* a) {
    354     return NewNode(machine()->ChangeFloat64ToInt32(), a);
    355   }
    356   Node* ChangeFloat64ToUint32(Node* a) {
    357     return NewNode(machine()->ChangeFloat64ToUint32(), a);
    358   }
    359   Node* ChangeInt32ToInt64(Node* a) {
    360     return NewNode(machine()->ChangeInt32ToInt64(), a);
    361   }
    362   Node* ChangeUint32ToUint64(Node* a) {
    363     return NewNode(machine()->ChangeUint32ToUint64(), a);
    364   }
    365   Node* TruncateFloat64ToInt32(Node* a) {
    366     return NewNode(machine()->TruncateFloat64ToInt32(), a);
    367   }
    368   Node* TruncateInt64ToInt32(Node* a) {
    369     return NewNode(machine()->TruncateInt64ToInt32(), a);
    370   }
    371 
    372   // Parameters.
    373   Node* Parameter(size_t index);
    374 
    375   // Control flow.
    376   Label* Exit();
    377   void Goto(Label* label);
    378   void Branch(Node* condition, Label* true_val, Label* false_val);
    379   // Call through CallFunctionStub with lazy deopt and frame-state.
    380   Node* CallFunctionStub0(Node* function, Node* receiver, Node* context,
    381                           Node* frame_state, CallFunctionFlags flags);
    382   // Call to a JS function with zero parameters.
    383   Node* CallJS0(Node* function, Node* receiver, Node* context,
    384                 Node* frame_state);
    385   // Call to a runtime function with zero parameters.
    386   Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context,
    387                      Node* frame_state);
    388   void Return(Node* value);
    389   void Bind(Label* label);
    390   void Deoptimize(Node* state);
    391 
    392   // Variables.
    393   Node* Phi(MachineType type, Node* n1, Node* n2) {
    394     return NewNode(common()->Phi(type, 2), n1, n2);
    395   }
    396   Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3) {
    397     return NewNode(common()->Phi(type, 3), n1, n2, n3);
    398   }
    399   Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3, Node* n4) {
    400     return NewNode(common()->Phi(type, 4), n1, n2, n3, n4);
    401   }
    402 
    403   // MachineAssembler is invalid after export.
    404   Schedule* Export();
    405 
    406  protected:
    407   virtual Node* MakeNode(const Operator* op, int input_count,
    408                          Node** inputs) FINAL;
    409 
    410   bool ScheduleValid() { return schedule_ != NULL; }
    411 
    412   Schedule* schedule() {
    413     DCHECK(ScheduleValid());
    414     return schedule_;
    415   }
    416 
    417  private:
    418   BasicBlock* Use(Label* label);
    419   BasicBlock* EnsureBlock(Label* label);
    420   BasicBlock* CurrentBlock();
    421 
    422   Schedule* schedule_;
    423   MachineOperatorBuilder machine_;
    424   CommonOperatorBuilder common_;
    425   MachineSignature* machine_sig_;
    426   CallDescriptor* call_descriptor_;
    427   Node** parameters_;
    428   Label exit_label_;
    429   BasicBlock* current_block_;
    430 
    431   DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
    432 };
    433 
    434 }  // namespace compiler
    435 }  // namespace internal
    436 }  // namespace v8
    437 
    438 #endif  // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
    439