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
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
|