Trying out a new style of JIT pattern matching.

This commit is contained in:
Ben Vanik
2014-05-26 20:28:21 -07:00
parent a001714fb0
commit 5a85263e5f
38 changed files with 6403 additions and 5160 deletions

39
src/alloy/hir/block.cc Normal file
View File

@@ -0,0 +1,39 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/hir/block.h>
#include <alloy/hir/instr.h>
using namespace alloy;
using namespace alloy::hir;
void Block::AssertNoCycles() {
Instr* hare = instr_head;
Instr* tortoise = instr_head;
if (!hare) {
return;
}
while (hare = hare->next) {
if (hare == tortoise) {
// Cycle!
XEASSERTALWAYS();
}
hare = hare->next;
if (hare == tortoise) {
// Cycle!
XEASSERTALWAYS();
}
tortoise = tortoise->next;
if (!hare || !tortoise) {
return;
}
}
}

View File

@@ -61,6 +61,8 @@ public:
Instr* instr_tail;
uint16_t ordinal;
void AssertNoCycles();
};

View File

@@ -92,7 +92,7 @@ void HIRBuilder::DumpValue(StringBuffer* str, Value* value) {
case INT8_TYPE: str->Append("%X", value->constant.i8); break;
case INT16_TYPE: str->Append("%X", value->constant.i16); break;
case INT32_TYPE: str->Append("%X", value->constant.i32); break;
case INT64_TYPE: str->Append("%X", value->constant.i64); break;
case INT64_TYPE: str->Append("%llX", value->constant.i64); break;
case FLOAT32_TYPE: str->Append("%F", value->constant.f32); break;
case FLOAT64_TYPE: str->Append("%F", value->constant.f64); break;
case VEC128_TYPE: str->Append("(%F,%F,%F,%F)",
@@ -252,6 +252,29 @@ void HIRBuilder::Dump(StringBuffer* str) {
}
}
void HIRBuilder::AssertNoCycles() {
Block* hare = block_head_;
Block* tortoise = block_head_;
if (!hare) {
return;
}
while (hare = hare->next) {
if (hare == tortoise) {
// Cycle!
XEASSERTALWAYS();
}
hare = hare->next;
if (hare == tortoise) {
// Cycle!
XEASSERTALWAYS();
}
tortoise = tortoise->next;
if (!hare || !tortoise) {
return;
}
}
}
Block* HIRBuilder::current_block() const {
return current_block_;
}
@@ -1729,16 +1752,19 @@ Value* HIRBuilder::Extract(Value* value, Value* index,
TypeName target_type) {
// TODO(benvanik): could do some of this as constants.
Value* trunc_index = index->type != INT8_TYPE ?
Truncate(index, INT8_TYPE) : index;
Instr* i = AppendInstr(
OPCODE_EXTRACT_info, 0,
AllocValue(target_type));
i->set_src1(value);
i->set_src2(ZeroExtend(index, INT64_TYPE));
i->set_src2(trunc_index);
i->src3.value = NULL;
return i->dest;
}
Value* HIRBuilder::Extract(Value* value, uint64_t index,
Value* HIRBuilder::Extract(Value* value, uint8_t index,
TypeName target_type) {
return Extract(value, LoadConstant(index), target_type);
}

View File

@@ -35,6 +35,7 @@ public:
virtual int Finalize();
void Dump(StringBuffer* str);
void AssertNoCycles();
Arena* arena() const { return arena_; }
@@ -196,7 +197,7 @@ public:
Value* Insert(Value* value, Value* index, Value* part);
Value* Insert(Value* value, uint64_t index, Value* part);
Value* Extract(Value* value, Value* index, TypeName target_type);
Value* Extract(Value* value, uint64_t index, TypeName target_type);
Value* Extract(Value* value, uint8_t index, TypeName target_type);
// i8->i16/i32/... (i8|i8 / i8|i8|i8|i8 / ...)
// i8/i16/i32 -> vec128
Value* Splat(Value* value, TypeName target_type);

View File

@@ -48,19 +48,6 @@ void Instr::set_src3(Value* value) {
src3_use = value ? value->AddUse(block->arena, this) : NULL;
}
bool Instr::Match(SignatureType dest_req,
SignatureType src1_req,
SignatureType src2_req,
SignatureType src3_req) const {
#define TO_SIG_TYPE(v) \
(v ? (v->IsConstant() ? SignatureType((v->type + 1) | SIG_TYPE_C) : SignatureType(v->type + 1)) : SIG_TYPE_X)
return
((dest_req == SIG_TYPE_IGNORE) || (dest_req == TO_SIG_TYPE(dest))) &&
((src1_req == SIG_TYPE_IGNORE) || (src1_req == TO_SIG_TYPE(src1.value))) &&
((src2_req == SIG_TYPE_IGNORE) || (src2_req == TO_SIG_TYPE(src2.value))) &&
((src3_req == SIG_TYPE_IGNORE) || (src3_req == TO_SIG_TYPE(src3.value)));
}
void Instr::MoveBefore(Instr* other) {
if (next == other) {
return;

View File

@@ -24,26 +24,6 @@ namespace hir {
class Block;
class Label;
enum SignatureType {
SIG_TYPE_X = 0,
SIG_TYPE_I8 = 1,
SIG_TYPE_I16 = 2,
SIG_TYPE_I32 = 3,
SIG_TYPE_I64 = 4,
SIG_TYPE_F32 = 5,
SIG_TYPE_F64 = 6,
SIG_TYPE_V128 = 7,
SIG_TYPE_C = (1 << 3),
SIG_TYPE_I8C = SIG_TYPE_C | SIG_TYPE_I8,
SIG_TYPE_I16C = SIG_TYPE_C | SIG_TYPE_I16,
SIG_TYPE_I32C = SIG_TYPE_C | SIG_TYPE_I32,
SIG_TYPE_I64C = SIG_TYPE_C | SIG_TYPE_I64,
SIG_TYPE_F32C = SIG_TYPE_C | SIG_TYPE_F32,
SIG_TYPE_F64C = SIG_TYPE_C | SIG_TYPE_F64,
SIG_TYPE_V128C = SIG_TYPE_C | SIG_TYPE_V128,
SIG_TYPE_IGNORE = 0xFF,
};
class Instr {
public:
Block* block;
@@ -74,11 +54,6 @@ public:
void set_src2(Value* value);
void set_src3(Value* value);
bool Match(SignatureType dest = SIG_TYPE_X,
SignatureType src1 = SIG_TYPE_X,
SignatureType src2 = SIG_TYPE_X,
SignatureType src3 = SIG_TYPE_X) const;
void MoveBefore(Instr* other);
void Replace(const OpcodeInfo* opcode, uint16_t flags);
void Remove();

View File

@@ -11,590 +11,590 @@
DEFINE_OPCODE(
OPCODE_COMMENT,
"comment",
OPCODE_SIG_X,
OPCODE_FLAG_IGNORE);
OPCODE_SIG_X_O,
OPCODE_FLAG_IGNORE)
DEFINE_OPCODE(
OPCODE_NOP,
"nop",
OPCODE_SIG_X,
OPCODE_FLAG_IGNORE);
OPCODE_FLAG_IGNORE)
DEFINE_OPCODE(
OPCODE_SOURCE_OFFSET,
"source_offset",
OPCODE_SIG_X_O,
OPCODE_FLAG_IGNORE | OPCODE_FLAG_HIDE);
OPCODE_FLAG_IGNORE | OPCODE_FLAG_HIDE)
DEFINE_OPCODE(
OPCODE_DEBUG_BREAK,
"debug_break",
OPCODE_SIG_X,
OPCODE_FLAG_VOLATILE);
OPCODE_FLAG_VOLATILE)
DEFINE_OPCODE(
OPCODE_DEBUG_BREAK_TRUE,
"debug_break_true",
OPCODE_SIG_X_V,
OPCODE_FLAG_VOLATILE);
OPCODE_FLAG_VOLATILE)
DEFINE_OPCODE(
OPCODE_TRAP,
"trap",
OPCODE_SIG_X,
OPCODE_FLAG_VOLATILE);
OPCODE_FLAG_VOLATILE)
DEFINE_OPCODE(
OPCODE_TRAP_TRUE,
"trap_true",
OPCODE_SIG_X_V,
OPCODE_FLAG_VOLATILE);
OPCODE_FLAG_VOLATILE)
DEFINE_OPCODE(
OPCODE_CALL,
"call",
OPCODE_SIG_X_S,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_CALL_TRUE,
"call_true",
OPCODE_SIG_X_V_S,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_CALL_INDIRECT,
"call_indirect",
OPCODE_SIG_X_V,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_CALL_INDIRECT_TRUE,
"call_indirect_true",
OPCODE_SIG_X_V_V,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_CALL_EXTERN,
"call_extern",
OPCODE_SIG_X_S,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_RETURN,
"return",
OPCODE_SIG_X,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_RETURN_TRUE,
"return_true",
OPCODE_SIG_X_V,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_SET_RETURN_ADDRESS,
"set_return_address",
OPCODE_SIG_X_V,
0);
0)
DEFINE_OPCODE(
OPCODE_BRANCH,
"branch",
OPCODE_SIG_X_L,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_BRANCH_TRUE,
"branch_true",
OPCODE_SIG_X_V_L,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_BRANCH_FALSE,
"branch_false",
OPCODE_SIG_X_V_L,
OPCODE_FLAG_BRANCH);
OPCODE_FLAG_BRANCH)
DEFINE_OPCODE(
OPCODE_ASSIGN,
"assign",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_CAST,
"cast",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_ZERO_EXTEND,
"zero_extend",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SIGN_EXTEND,
"sign_extend",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_TRUNCATE,
"truncate",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_CONVERT,
"convert",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_ROUND,
"round",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_CONVERT_I2F,
"vector_convert_i2f",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_CONVERT_F2I,
"vector_convert_f2i",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOAD_VECTOR_SHL,
"load_vector_shl",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOAD_VECTOR_SHR,
"load_vector_shr",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOAD_CLOCK,
"load_clock",
OPCODE_SIG_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOAD_LOCAL,
"load_local",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_STORE_LOCAL,
"store_local",
OPCODE_SIG_X_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOAD_CONTEXT,
"load_context",
OPCODE_SIG_V_O,
0);
0)
DEFINE_OPCODE(
OPCODE_STORE_CONTEXT,
"store_context",
OPCODE_SIG_X_O_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOAD,
"load",
OPCODE_SIG_V_V,
OPCODE_FLAG_MEMORY);
OPCODE_FLAG_MEMORY)
DEFINE_OPCODE(
OPCODE_STORE,
"store",
OPCODE_SIG_X_V_V,
OPCODE_FLAG_MEMORY);
OPCODE_FLAG_MEMORY)
DEFINE_OPCODE(
OPCODE_PREFETCH,
"prefetch",
OPCODE_SIG_X_V_O,
0);
0)
DEFINE_OPCODE(
OPCODE_MAX,
"max",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_MIN,
"min",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SELECT,
"select",
OPCODE_SIG_V_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_IS_TRUE,
"is_true",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_IS_FALSE,
"is_false",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_EQ,
"compare_eq",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_COMPARE_NE,
"compare_ne",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_COMPARE_SLT,
"compare_slt",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_SLE,
"compare_sle",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_SGT,
"compare_sgt",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_SGE,
"compare_sge",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_ULT,
"compare_ult",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_ULE,
"compare_ule",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_UGT,
"compare_ugt",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_UGE,
"compare_uge",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_DID_CARRY,
"did_carry",
OPCODE_SIG_V_V,
OPCODE_FLAG_PAIRED_PREV);
OPCODE_FLAG_PAIRED_PREV)
DEFINE_OPCODE(
OPCODE_DID_OVERFLOW,
"did_overflow",
OPCODE_SIG_V_V,
OPCODE_FLAG_PAIRED_PREV);
OPCODE_FLAG_PAIRED_PREV)
DEFINE_OPCODE(
OPCODE_DID_SATURATE,
"did_saturate",
OPCODE_SIG_V_V,
OPCODE_FLAG_PAIRED_PREV);
OPCODE_FLAG_PAIRED_PREV)
DEFINE_OPCODE(
OPCODE_VECTOR_COMPARE_EQ,
"vector_compare_eq",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_VECTOR_COMPARE_SGT,
"vector_compare_sgt",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_COMPARE_SGE,
"vector_compare_sge",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_COMPARE_UGT,
"vector_compare_ugt",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_COMPARE_UGE,
"vector_compare_uge",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_ADD,
"add",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_ADD_CARRY,
"add_carry",
OPCODE_SIG_V_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_ADD,
"vector_add",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_SUB,
"sub",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_MUL,
"mul",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_MUL_HI,
"mul_hi",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_DIV,
"div",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_MUL_ADD,
"mul_add",
OPCODE_SIG_V_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_MUL_SUB,
"mul_sub",
OPCODE_SIG_V_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_NEG,
"neg",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_ABS,
"abs",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SQRT,
"sqrt",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_RSQRT,
"rsqrt",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_POW2,
"pow2",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_LOG2,
"log2",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_DOT_PRODUCT_3,
"dot_product_3",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_DOT_PRODUCT_4,
"dot_product_4",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_AND,
"and",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_OR,
"or",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_XOR,
"xor",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_COMMUNATIVE);
OPCODE_FLAG_COMMUNATIVE)
DEFINE_OPCODE(
OPCODE_NOT,
"not",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SHL,
"shl",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_SHL,
"vector_shl",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SHR,
"shr",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_SHR,
"vector_shr",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SHA,
"sha",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_VECTOR_SHA,
"vector_sha",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_ROTATE_LEFT,
"rotate_left",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_BYTE_SWAP,
"byte_swap",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_CNTLZ,
"cntlz",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_INSERT,
"insert",
OPCODE_SIG_V_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_EXTRACT,
"extract",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SPLAT,
"splat",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_PERMUTE,
"permute",
OPCODE_SIG_V_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_SWIZZLE,
"swizzle",
OPCODE_SIG_V_V_O,
0);
0)
DEFINE_OPCODE(
OPCODE_PACK,
"pack",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_UNPACK,
"unpack",
OPCODE_SIG_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_COMPARE_EXCHANGE,
"compare_exchange",
OPCODE_SIG_V_V_V_V,
OPCODE_FLAG_VOLATILE);
OPCODE_FLAG_VOLATILE)
DEFINE_OPCODE(
OPCODE_ATOMIC_EXCHANGE,
"atomic_exchange",
OPCODE_SIG_V_V_V,
OPCODE_FLAG_VOLATILE);
OPCODE_FLAG_VOLATILE)
DEFINE_OPCODE(
OPCODE_ATOMIC_ADD,
"atomic_add",
OPCODE_SIG_V_V_V,
0);
0)
DEFINE_OPCODE(
OPCODE_ATOMIC_SUB,
"atomic_sub",
OPCODE_SIG_V_V_V,
0);
0)

View File

@@ -1,6 +1,7 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'block.cc',
'block.h',
'hir_builder.cc',
'hir_builder.h',

View File

@@ -560,6 +560,26 @@ void Value::ByteSwap() {
}
}
void Value::CountLeadingZeros(const ConstantValue& src) {
switch (type) {
case INT8_TYPE:
constant.i8 = __lzcnt16(src.i8) - 8;
break;
case INT16_TYPE:
constant.i8 = __lzcnt16(src.i16);
break;
case INT32_TYPE:
constant.i8 = __lzcnt(src.i32);
break;
case INT64_TYPE:
constant.i8 = __lzcnt64(src.i64);
break;
default:
XEASSERTALWAYS();
break;
}
}
bool Value::Compare(Opcode opcode, Value* other) {
// TODO(benvanik): big matrix.
XEASSERTALWAYS();

View File

@@ -68,6 +68,10 @@ enum ValueFlags {
VALUE_IS_ALLOCATED = (1 << 2), // Used by backends. Do not set.
};
struct RegAssignment {
const backend::MachineInfo::RegisterSet* set;
int32_t index;
};
class Value {
public:
@@ -91,10 +95,7 @@ public:
TypeName type;
uint32_t flags;
struct {
const backend::MachineInfo::RegisterSet* set;
int32_t index;
} reg;
RegAssignment reg;
ConstantValue constant;
Instr* def;
@@ -392,6 +393,7 @@ public:
void Shr(Value* other);
void Sha(Value* other);
void ByteSwap();
void CountLeadingZeros(const ConstantValue& src);
bool Compare(Opcode opcode, Value* other);
};