29
TmpVar::TmpVar(var_idx_t _idx, int _cls, TypeExpr* _type, SymDef* sym, const SrcLocation* loc)
30
: v_type(_type), idx(_idx), cls(_cls), coord(0) {
33
sym->value->idx = _idx;
36
where = std::make_unique<SrcLocation>(*loc);
39
v_type = TypeExpr::new_hole();
46
void TmpVar::set_location(const SrcLocation& loc) {
50
where = std::make_unique<SrcLocation>(loc);
54
void TmpVar::dump(std::ostream& os) const {
56
os << " : " << v_type << " (width ";
57
v_type->show_width(os);
60
os << " = _" << (coord >> 8) << '.' << (coord & 255);
61
} else if (coord < 0) {
62
int n = (~coord >> 8), k = (~coord & 0xff);
64
os << " = (_" << n << ".._" << (n + k - 1) << ")";
72
void TmpVar::show(std::ostream& os, int omit_idx) const {
74
os << sym::symbols.get_name(name);
75
if (omit_idx && (omit_idx >= 2 || (cls & _UniqueName))) {
82
std::ostream& operator<<(std::ostream& os, const TmpVar& var) {
87
void VarDescr::show_value(std::ostream& os) const {
124
if (int_const.not_null()) {
125
os << '=' << int_const;
129
void VarDescr::show(std::ostream& os, const char* name) const {
133
if (flags & _Unused) {
143
void VarDescr::set_const(long long value) {
144
return set_const(td::make_refint(value));
147
void VarDescr::set_const(td::RefInt256 value) {
148
int_const = std::move(value);
149
if (!int_const->signed_fits_bits(257)) {
150
int_const.write().invalidate();
153
int s = sgn(int_const);
155
val |= _Nan | _NonZero;
157
val |= _NonZero | _Neg | _Finite;
158
if (*int_const == -1) {
162
val |= _NonZero | _Pos | _Finite;
167
val |= _Zero | _Neg | _Pos | _Finite | _Bool | _Bit;
170
val |= int_const->get_bit(0) ? _Odd : _Even;
174
void VarDescr::set_const(std::string value) {
179
void VarDescr::set_const_nan() {
180
set_const(td::make_refint());
183
void VarDescr::operator|=(const VarDescr& y) {
185
if (is_int_const() && y.is_int_const() && cmp(int_const, y.int_const) != 0) {
188
if (!(val & _Const)) {
193
void VarDescr::operator&=(const VarDescr& y) {
195
if (y.int_const.not_null() && int_const.is_null()) {
196
int_const = y.int_const;
200
void VarDescr::set_value(const VarDescr& y) {
202
int_const = y.int_const;
205
void VarDescr::set_value(VarDescr&& y) {
207
int_const = std::move(y.int_const);
210
void VarDescr::clear_value() {
215
void VarDescrList::show(std::ostream& os) const {
217
os << "<unreachable> ";
220
for (const auto& v : list) {
226
void Op::flags_set_clear(int set, int clear) {
227
flags = (flags | set) & ~clear;
228
for (auto& op : block0) {
229
op.flags_set_clear(set, clear);
231
for (auto& op : block1) {
232
op.flags_set_clear(set, clear);
235
void Op::split_vars(const std::vector<TmpVar>& vars) {
236
split_var_list(left, vars);
237
split_var_list(right, vars);
238
for (auto& op : block0) {
241
for (auto& op : block1) {
246
void Op::split_var_list(std::vector<var_idx_t>& var_list, const std::vector<TmpVar>& vars) {
247
int new_size = 0, changes = 0;
248
for (var_idx_t v : var_list) {
249
int c = vars.at(v).coord;
252
new_size += (~c & 0xff);
260
std::vector<var_idx_t> new_var_list;
261
new_var_list.reserve(new_size);
262
for (var_idx_t v : var_list) {
263
int c = vars.at(v).coord;
265
int n = (~c >> 8), k = (~c & 0xff);
267
new_var_list.push_back(n++);
270
new_var_list.push_back(v);
273
var_list = std::move(new_var_list);
276
void Op::show(std::ostream& os, const std::vector<TmpVar>& vars, std::string pfx, int mode) const {
279
for (const auto& v : var_info.list) {
281
if (v.flags & VarDescr::_Last) {
284
if (v.flags & VarDescr::_Unused) {
295
std::string dis = disabled() ? "<disabled> " : "";
304
os << pfx << dis << "???\n";
307
os << pfx << dis << "NOP\n";
310
os << pfx << dis << "CALL: ";
311
show_var_list(os, left, vars);
312
os << " := " << (fun_ref ? fun_ref->name() : "(null)") << " ";
313
if ((mode & 4) && args.size() == right.size()) {
314
show_var_list(os, args, vars);
316
show_var_list(os, right, vars);
321
os << pfx << dis << "CALLIND: ";
322
show_var_list(os, left, vars);
324
show_var_list(os, right, vars);
328
os << pfx << dis << "LET ";
329
show_var_list(os, left, vars);
331
show_var_list(os, right, vars);
335
os << pfx << dis << "MKTUPLE ";
336
show_var_list(os, left, vars);
338
show_var_list(os, right, vars);
342
os << pfx << dis << "UNTUPLE ";
343
show_var_list(os, left, vars);
345
show_var_list(os, right, vars);
349
os << pfx << dis << "CONST ";
350
show_var_list(os, left, vars);
351
os << " := " << int_const << std::endl;
354
os << pfx << dis << "SCONST ";
355
show_var_list(os, left, vars);
356
os << " := " << str_const << std::endl;
359
os << pfx << dis << "IMPORT ";
360
show_var_list(os, left, vars);
364
os << pfx << dis << "RETURN ";
365
show_var_list(os, left, vars);
369
os << pfx << dis << "GLOBVAR ";
370
show_var_list(os, left, vars);
371
os << " := " << (fun_ref ? fun_ref->name() : "(null)") << std::endl;
374
os << pfx << dis << "SETGLOB ";
375
os << (fun_ref ? fun_ref->name() : "(null)") << " := ";
376
show_var_list(os, right, vars);
380
os << pfx << dis << "REPEAT ";
381
show_var_list(os, left, vars);
383
show_block(os, block0.get(), vars, pfx, mode);
387
os << pfx << dis << "IF ";
388
show_var_list(os, left, vars);
390
show_block(os, block0.get(), vars, pfx, mode);
392
show_block(os, block1.get(), vars, pfx, mode);
396
os << pfx << dis << "WHILE ";
397
show_var_list(os, left, vars);
399
show_block(os, block0.get(), vars, pfx, mode);
401
show_block(os, block1.get(), vars, pfx, mode);
405
os << pfx << dis << "UNTIL ";
406
show_var_list(os, left, vars);
408
show_block(os, block0.get(), vars, pfx, mode);
412
os << pfx << dis << "AGAIN ";
413
show_var_list(os, left, vars);
415
show_block(os, block0.get(), vars, pfx, mode);
419
os << pfx << dis << "<???" << cl << "> ";
420
show_var_list(os, left, vars);
422
show_var_list(os, right, vars);
428
void Op::show_var_list(std::ostream& os, const std::vector<var_idx_t>& idx_list,
429
const std::vector<TmpVar>& vars) const {
430
if (!idx_list.size()) {
432
} else if (idx_list.size() == 1) {
433
os << vars.at(idx_list[0]);
435
os << "(" << vars.at(idx_list[0]);
436
for (std::size_t i = 1; i < idx_list.size(); i++) {
437
os << "," << vars.at(idx_list[i]);
443
void Op::show_var_list(std::ostream& os, const std::vector<VarDescr>& list, const std::vector<TmpVar>& vars) const {
444
auto n = list.size();
449
for (std::size_t i = 0; i < list.size(); i++) {
453
if (list[i].is_unused()) {
456
os << vars.at(list[i].idx) << ':';
457
list[i].show_value(os);
463
void Op::show_block(std::ostream& os, const Op* block, const std::vector<TmpVar>& vars, std::string pfx, int mode) {
464
os << "{" << std::endl;
465
std::string pfx2 = pfx + " ";
466
for (const Op& op : block) {
467
op.show(os, vars, pfx2, mode);
472
void CodeBlob::flags_set_clear(int set, int clear) {
473
for (auto& op : ops) {
474
op.flags_set_clear(set, clear);
478
std::ostream& operator<<(std::ostream& os, const CodeBlob& code) {
484
void CodeBlob::print(std::ostream& os, int flags) const {
485
os << "CODE BLOB: " << var_cnt << " variables, " << in_var_cnt << " input\n";
486
if ((flags & 8) != 0) {
487
for (const auto& var : vars) {
489
if (var.where && (flags & 1) != 0) {
491
os << " defined here:\n";
492
var.where->show_context(os);
496
os << "------- BEGIN --------\n";
497
for (const auto& op : ops) {
498
op.show(os, vars, "", flags);
500
os << "-------- END ---------\n\n";
503
var_idx_t CodeBlob::create_var(int cls, TypeExpr* var_type, SymDef* sym, const SrcLocation* location) {
504
vars.emplace_back(var_cnt, cls, var_type, sym, location);
506
sym->value->idx = var_cnt;
511
bool CodeBlob::import_params(FormalArgList arg_list) {
512
if (var_cnt || in_var_cnt || op_cnt) {
515
std::vector<var_idx_t> list;
516
for (const auto& par : arg_list) {
520
std::tie(arg_type, arg_sym, arg_loc) = par;
521
list.push_back(create_var(arg_sym ? (TmpVar::_In | TmpVar::_Named) : TmpVar::_In, arg_type, arg_sym, &arg_loc));
523
emplace_back(loc, Op::_Import, list);
524
in_var_cnt = var_cnt;