// Remove dead instructions by doing a traditional liveness analysis. // instructions that mutate memory, physical registers, or status flags // are considered useful. All branches are considered useful. // // Given SSA, there's a faster sparse version of this algorithm that marks // useful instructions in one pass, then transitively marks pure instructions // that define inputs to useful instructions. However it requires a mapping // from vreg numbers to the instruction that defines them, and a way to address // individual instructions. // // We could remove useless branches by computing the post-dominator tree and // RDF(b) for each block; then a branch is only useful if it controls whether // or not a useful block executes, and useless branches can be forwarded to // the nearest useful post-dominator. void removeDeadCode(Vunit& unit) { auto blocks = sortBlocks(unit); jit::vector<LiveSet> livein(unit.blocks.size()); LiveSet live(unit.next_vr); auto pass = [&](bool mutate) { bool changed = false; for (auto blockIt = blocks.end(); blockIt != blocks.begin();) { auto b = *--blockIt; auto& block = unit.blocks[b]; live.reset(); for (auto s : succs(block)) { if (!livein[s].empty()) { live |= livein[s]; } } for (auto i = block.code.end(); i != block.code.begin();) { auto& inst = *--i; auto useful = effectful(inst); visitDefs(unit, inst, [&](Vreg r) { if (r.isPhys() || live.test(r)) { useful = true; live.reset(r); } }); if (useful) { visitUses(unit, inst, [&](Vreg r) { live.set(r); }); } else if (mutate) { inst = nop{}; changed = true; } } if (mutate) { assert(live == livein[b]); } else { if (live != livein[b]) { livein[b] = live; changed = true; } } } return changed; }; // analyze until livein reaches a fixed point while (pass(false)) {} // nop-out useless instructions if (pass(true)) { for (auto b : blocks) { auto& code = unit.blocks[b].code; auto end = std::remove_if(code.begin(), code.end(), [&](Vinstr& inst) { return inst.op == Vinstr::nop; }); code.erase(end, code.end()); } printUnit(kVasmDCELevel, "after vasm-dead", unit); } }
bool checkTmpsSpanningCalls(const IRUnit& unit) { // CallBuiltin is ok because it is not a php-level call. (It will // call a C++ helper and we can push/pop around it normally.) auto isCall = [&] (Opcode op) { return op == Call || op == CallArray || op == ContEnter; }; auto ignoreSrc = [&](IRInstruction& inst, SSATmp* src) { /* * ReDefSP, TakeStack, and FramePtr/StkPtr-typed tmps are used * only for stack analysis in the simplifier and therefore may * live across calls. In particular, ReDefSP are used to bridge * the logical stack of the caller when a callee is inlined so * that analysis does not scan into the callee stack when * searching for a type of value in the caller. * * Tmps defined by DefConst are always available and may be * assigned to registers if needed by the instructions using the * const. */ return (inst.is(ReDefSP) && src->isA(Type::StkPtr)) || inst.is(TakeStack) || src->isA(Type::StkPtr) || src->isA(Type::FramePtr) || src->inst()->is(DefConst); }; StateVector<Block,IdSet<SSATmp>> livein(unit, IdSet<SSATmp>()); bool isValid = true; postorderWalk(unit, [&](Block* block) { auto& live = livein[block]; if (auto taken = block->taken()) live = livein[taken]; if (auto next = block->next()) live |= livein[next]; for (auto it = block->end(); it != block->begin();) { auto& inst = *--it; for (auto& dst : inst.dsts()) { live.erase(dst); } if (isCall(inst.op())) { live.forEach([&](uint32_t tmp) { auto msg = folly::format("checkTmpsSpanningCalls failed\n" " instruction: {}\n" " src: t{}\n", inst.toString(), tmp).str(); std::cerr << msg; FTRACE(1, "{}", msg); isValid = false; }); } for (auto* src : inst.srcs()) { if (!ignoreSrc(inst, src)) live.add(src); } } }); return isValid; }
// Remove dead instructions by doing a traditional liveness analysis. // instructions that mutate memory, physical registers, or status flags // are considered useful. All branches are considered useful. // // Given SSA, there's a faster sparse version of this algorithm that marks // useful instructions in one pass, then transitively marks pure instructions // that define inputs to useful instructions. However it requires a mapping // from vreg numbers to the instruction that defines them, and a way to address // individual instructions. // // We could remove useless branches by computing the post-dominator tree and // RDF(b) for each block; then a branch is only useful if it controls whether // or not a useful block executes, and useless branches can be forwarded to // the nearest useful post-dominator. void removeDeadCode(Vunit& unit) { Timer timer(Timer::vasm_dce); auto blocks = sortBlocks(unit); jit::vector<LiveSet> livein(unit.blocks.size()); LiveSet live(unit.next_vr); auto pass = [&](bool mutate) { bool changed = false; for (auto blockIt = blocks.end(); blockIt != blocks.begin();) { auto b = *--blockIt; auto& block = unit.blocks[b]; live.reset(); for (auto s : succs(block)) { if (!livein[s].empty()) { live |= livein[s]; } } for (auto i = block.code.end(); i != block.code.begin();) { auto& inst = *--i; auto useful = effectful(inst); visitDefs(unit, inst, [&](Vreg r) { if (r.isPhys() || live.test(r)) { useful = true; live.reset(r); } }); if (useful) { visitUses(unit, inst, [&](Vreg r) { live.set(r); }); } else if (mutate) { inst = nop{}; changed = true; } } if (mutate) { assertx(live == livein[b]); } else { if (live != livein[b]) { livein[b] = live; changed = true; } } } return changed; }; // analyze until livein reaches a fixed point while (pass(false)) {} auto const changed = pass(true); removeTrivialNops(unit); if (changed) { printUnit(kVasmDCELevel, "after vasm-dead", unit); } }
Liveinfo::Liveinfo(int getroom,QWidget *parent) : QDialog(parent), Leavebool(true),Liveinbool(true) { RoomNum = getroom; QSqlQueryModel roomtable;// = new QSqlQueryModel; roomtable.setQuery("select * from Room;"); QSqlQueryModel recordtable;// = new QSqlQueryModel; recordtable.setQuery("select * from Record,Guest;"); int Check_live = 0; QString Snum; QString Sname; QString SID; QString Scontact; QString Stime; QString Etime; for (int i = 0; i < roomtable.rowCount(); ++i) { QSqlRecord roomrecord = roomtable.record(i); int Rnum = roomrecord.value("Num").toInt(); if( Rnum == getroom ) { Check_live = roomrecord.value("Live").toInt(); Snum = roomrecord.value("Num").toString(); Sprice = roomrecord.value("Price").toString(); if(Check_live == 1) { for (int j = 0; j < recordtable.rowCount(); ++j) { QSqlRecord Recordrecord = recordtable.record(j); Rnum = Recordrecord.value("Num").toInt(); if( Rnum == getroom ) { Sname = Recordrecord.value("Name").toString(); Sdays = Recordrecord.value("Days").toString(); Sdeposit = Recordrecord.value("Deposit").toString(); SID = Recordrecord.value("ID").toString(); Scontact = Recordrecord.value("Contact").toString(); Stime = Recordrecord.value("Stime").toString(); Etime = Recordrecord.value("Etime").toString(); } } } break; } }//Got the roon num and chek if the room have lived QGridLayout* mainlayout = new QGridLayout; QGridLayout* buttonlayout = new QGridLayout; QLabel* Name = new QLabel("Name"); QLabel* Contact = new QLabel("Contact"); QLabel* ID = new QLabel("ID"); QLabel* Days = new QLabel("Days"); QLabel* Despoit = new QLabel("Despoit"); QLabel* RoomNum = new QLabel("Room Num"); QLabel* Price = new QLabel("Price"); QLabel* Livein = new QLabel("Live in day"); QLabel* LeaveDay = new QLabel("Leave day"); NameEdit = new QLineEdit; ContactEdit = new QLineEdit; IDEdit = new QLineEdit; DaysEdit = new QLineEdit; DespoitEdit = new QLineEdit; RoomNumEdit = new QLineEdit; /* PriceEdit = new QLineEdit; LiveinEdit = new QLineEdit; LeaveEdit = new QLineEdit; */ QLineEdit* PriceEdit = new QLineEdit; QLineEdit* LiveinEdit = new QLineEdit; QLineEdit* LeaveEdit = new QLineEdit; QPushButton* Modify = new QPushButton("Modify"); QPushButton* Check_out = new QPushButton("Check Out"); QPushButton* Submit = new QPushButton("Submit"); QPushButton* Cancel = new QPushButton("Cancel"); PriceEdit->setText(Sprice); RoomNumEdit->setText(Snum); QDate a = QDate::currentDate(); Estime = a.toString("yyyy-MM-dd"); if(Check_live == 1) //show the Record infomation { leave(); NameEdit->setText(Sname); ContactEdit->setText(Scontact); IDEdit->setText(SID); DaysEdit->setText(Sdays); DespoitEdit->setText(Sdeposit); LiveinEdit->setText(Stime); LeaveEdit->setText(Etime); } else { livein(); LiveinEdit->setText(Estime); } LeaveDay->setEnabled(Liveinbool); LeaveEdit->setEnabled(Liveinbool); Modify->setEnabled(false); Check_out->setEnabled(Liveinbool); Submit->setEnabled(Leavebool); connect(Submit, SIGNAL(clicked()), this, SLOT(SubmitButton())); connect(Modify, SIGNAL(clicked()), this, SLOT(ModifyButton())); connect(Check_out, SIGNAL(clicked()), this, SLOT(CheckoutButton())); connect(Cancel, SIGNAL(clicked()), this, SLOT(CancelButton())); mainlayout->addWidget(Name,0,0,1,1); mainlayout->addWidget(Contact,0,2,1,1); mainlayout->addWidget(ID,1,0,1,1); mainlayout->addWidget(Days,2,0,1,1); mainlayout->addWidget(Despoit,2,2,1,1); mainlayout->addWidget(RoomNum,3,0,1,1); mainlayout->addWidget(Price,3,2,1,1); mainlayout->addWidget(Livein,4,0,1,1); mainlayout->addWidget(NameEdit,0,1,1,1); mainlayout->addWidget(ContactEdit,0,3,1,1); mainlayout->addWidget(IDEdit,1,1,1,3); mainlayout->addWidget(DaysEdit,2,1,1,1); mainlayout->addWidget(DespoitEdit,2,3,1,1); mainlayout->addWidget(RoomNumEdit,3,1,1,1); mainlayout->addWidget(PriceEdit,3,3,1,1); mainlayout->addWidget(LiveinEdit,4,1,1,1); mainlayout->addWidget(LeaveDay,4,2,1,1); mainlayout->addWidget(LeaveEdit,4,3,1,1); buttonlayout->addWidget(Submit,0,0,1,1); buttonlayout->addWidget(Modify,0,1,1,1); buttonlayout->addWidget(Check_out,0,2,1,1); buttonlayout->addWidget(Cancel,0,3,1,1); QVBoxLayout *Layout = new QVBoxLayout; Layout->addLayout(mainlayout); Layout->addLayout(buttonlayout); setLayout(Layout); // setWindow(200,300,400,500); setWindowTitle("Record"); }