You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
4.2 KiB

#ifndef SYSYCOMPILER_REGALLOC_H
#define SYSYCOMPILER_REGALLOC_H
#include "lir.h"
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <set>
#include <algorithm>
#include <string>
#include <queue>
class LIRFunction;
class LIRModule;
class LIROperand;
#define INST_GAP 1
#define REGALLOC_SPILL 66666
#define REGALLOC_DEF_NO_USE 7777777
#define TOP_LIMIT_PHYS_REG 12
#define BOTTOM_LIMIT_PHYS_FREG -31
#define PHYS_REG_NUM (TOP_LIMIT_PHYS_REG)
#define PHYS_FREG_NUM (-(BOTTOM_LIMIT_PHYS_FREG))
class RegAlloc{
public:
using Pii = std::pair<unsigned int, unsigned int>;
using Var_live_intervals = std::list<Pii>;
using Var_live_map = std::unordered_map< LIROperand*, Var_live_intervals>;
using Var_reg_map = std::unordered_map< LIROperand*, int> ;
using Inst_label = std::unordered_map< LIRInstruction*, unsigned int> ;
using Label_inst = std::unordered_map< unsigned int, LIRInstruction* > ;
using Bb_valset_map = std::unordered_map< LIRBasicBlock*, std::set< LIROperand*> > ;
using Bb_valvec_map = std::unordered_map< LIRBasicBlock*, std::vector< LIROperand*> >;
using Bb_interval = std::unordered_map< LIRBasicBlock*, Pii>;
class varIntervalsCmp {
public:
bool operator()(const std::pair<RegAlloc::Pii*, LIROperand*> &A, const std::pair<RegAlloc::Pii*, LIROperand*> &B) const {
RegAlloc::Pii *a = A.first, *b = B.first;
if(a->second != b->second)
return a->second < b->second;
else if(a->first != b->first)
return a->first > b->first;
else
return A.second < B.second;
}
};
LIRFunction* lirf_;
LIRModule* lirm_;
RegAlloc(LIRFunction* lirf,bool is_o2){
this->lirf_ = lirf;
this->lirm_ = lirf->parent_;
this->is_o2_ = is_o2;
}
~RegAlloc()=default;
void run();
void process_code();
int getReg(LIROperand* lirop, LIRInstruction* inst);
void preF();
void assignForFunc();
void live_analyse();
void live_analyse_1();
void live_analyse_2();
void live_analyse_3();
void linearScan();
void releaseOverdueIntervals(std::set< std::pair<Pii*, LIROperand*>, varIntervalsCmp>& ,std::unordered_map<int, int>&,unsigned int &,Pii* , bool);
void assginFreeReg(std::set< std::pair<Pii*, LIROperand*>, varIntervalsCmp>& ,std::unordered_map<int, int>&,unsigned int &,Pii* , bool);
bool is_o2_;
LIRBasicBlock* retBB = nullptr;
LIRBasicBlock* initBB =nullptr;
Pii func_end = Pii(REGALLOC_DEF_NO_USE, REGALLOC_DEF_NO_USE);
std::unordered_map<LIRBasicBlock*,unsigned int> FEdge;
std::vector<LIRBasicBlock*> basicBlocksOrder;
std::unordered_set<LIRBasicBlock*> basicBlocksOrderSet ;
std::unordered_set<LIRBasicBlock*> visited;
Bb_valset_map live_def;
Bb_valvec_map live_use;
Bb_valvec_map live_out;
Bb_valvec_map live_in;
std::unordered_map< int, Var_live_intervals> intervals_token_phys_reg;
Var_live_map intervals;
Var_reg_map assignReg;
Inst_label instIdx;
Label_inst idxInst;
Bb_interval bbInterval;
std::vector<Pii*> all_intervals;
std::unordered_map<Pii*, LIROperand*> interval_belong_umap;
std::unordered_map<Pii*, int> final_result_;
std::unordered_map<LIROperand*,std::unordered_map<LIRInstruction*,Pii*> > opnd_inst_in_itv;
static inline bool isVF(const LIROperand * var) {return var->tid_ == LIROperand::LOPhysFRegTy;}
static inline bool isVNF(const LIROperand * var) {return var->tid_ == LIROperand::LOVirtRegTy;}
void computeBlockOrder();
void addIntervalAtBack_positive(LIROperand* phy_reg, unsigned int begin, unsigned int end);
void addIntervalAtBack_positive(int cond, unsigned int inst_idx);
Pii* addInterval(LIROperand* val_ptr, unsigned int bb_begin,unsigned int bb_end , bool bb_range);
Pii* cutInterval(LIROperand *var_ptr, unsigned int cut_point, LIRInstruction* inst , LIRInstruction* last_inst );
unsigned int getInstIdx( LIRInstruction* inst_ptr) { return instIdx[inst_ptr]; }
bool isConflict(Pii *now_interval,int);
void dfs(LIRBasicBlock*);
void findRetBB(LIRBasicBlock*);
bool isRelevant(LIROperand*,LIRInstruction*);
int is_KF_hasR_noUse(LIRInstruction* inst);
};
#endif