Allow X86 QBE to be extended
Enhancements and updates to allow X86Mir2LIR Backend to be subclassed
for experimentation. Add virtual in a whole bunch of places, and make
some other changes to get this to work.
Change-Id: I0980a19bc5d5725f91660f98c95f1f51c17ee9b6
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 687c41d..7f0bf30 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -485,6 +485,7 @@
LIRSlowPath(Mir2Lir* m2l, const DexOffset dexpc, LIR* fromfast,
LIR* cont = nullptr) :
m2l_(m2l), cu_(m2l->cu_), current_dex_pc_(dexpc), fromfast_(fromfast), cont_(cont) {
+ m2l->StartSlowPath(cont);
}
virtual ~LIRSlowPath() {}
virtual void Compile() = 0;
@@ -493,6 +494,14 @@
return arena->Alloc(size, kArenaAllocData);
}
+ LIR *GetContinuationLabel() {
+ return cont_;
+ }
+
+ LIR *GetFromFast() {
+ return fromfast_;
+ }
+
protected:
LIR* GenerateTargetLabel(int opcode = kPseudoTargetLabel);
@@ -583,7 +592,7 @@
virtual void Materialize();
virtual CompiledMethod* GetCompiledMethod();
void MarkSafepointPC(LIR* inst);
- void SetupResourceMasks(LIR* lir);
+ void SetupResourceMasks(LIR* lir, bool leave_mem_ref = false);
void SetMemRefType(LIR* lir, bool is_load, int mem_type);
void AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load, bool is64bit);
void SetupRegMask(uint64_t* mask, int reg);
@@ -625,6 +634,12 @@
LIR* InsertCaseLabel(DexOffset vaddr, int keyVal);
void MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec);
void MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec);
+
+ virtual void StartSlowPath(LIR *label) {}
+ virtual void BeginInvoke(CallInfo* info) {}
+ virtual void EndInvoke(CallInfo* info) {}
+
+
// Handle bookkeeping to convert a wide RegLocation to a narow RegLocation. No code generated.
RegLocation NarrowRegLoc(RegLocation loc);
@@ -632,7 +647,7 @@
void ConvertMemOpIntoMove(LIR* orig_lir, RegStorage dest, RegStorage src);
void ApplyLoadStoreElimination(LIR* head_lir, LIR* tail_lir);
void ApplyLoadHoisting(LIR* head_lir, LIR* tail_lir);
- void ApplyLocalOptimizations(LIR* head_lir, LIR* tail_lir);
+ virtual void ApplyLocalOptimizations(LIR* head_lir, LIR* tail_lir);
// Shared by all targets - implemented in ralloc_util.cc
int GetSRegHi(int lowSreg);
@@ -656,18 +671,18 @@
RegStorage AllocPreservedSingle(int s_reg);
virtual RegStorage AllocPreservedDouble(int s_reg);
RegStorage AllocTempBody(GrowableArray<RegisterInfo*> ®s, int* next_temp, bool required);
- RegStorage AllocFreeTemp();
- RegStorage AllocTemp();
- RegStorage AllocTempSingle();
- RegStorage AllocTempDouble();
+ virtual RegStorage AllocFreeTemp();
+ virtual RegStorage AllocTemp();
+ virtual RegStorage AllocTempSingle();
+ virtual RegStorage AllocTempDouble();
void FlushReg(RegStorage reg);
void FlushRegWide(RegStorage reg);
RegStorage AllocLiveReg(int s_reg, int reg_class, bool wide);
RegStorage FindLiveReg(GrowableArray<RegisterInfo*> ®s, int s_reg);
- void FreeTemp(RegStorage reg);
- void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free);
- bool IsLive(RegStorage reg);
- bool IsTemp(RegStorage reg);
+ virtual void FreeTemp(RegStorage reg);
+ virtual void FreeRegLocTemps(RegLocation rl_keep, RegLocation rl_free);
+ virtual bool IsLive(RegStorage reg);
+ virtual bool IsTemp(RegStorage reg);
bool IsPromoted(RegStorage reg);
bool IsDirty(RegStorage reg);
void LockTemp(RegStorage reg);
@@ -675,7 +690,7 @@
void NullifyRange(RegStorage reg, int s_reg);
void MarkDef(RegLocation rl, LIR *start, LIR *finish);
void MarkDefWide(RegLocation rl, LIR *start, LIR *finish);
- RegLocation WideToNarrow(RegLocation rl);
+ virtual RegLocation WideToNarrow(RegLocation rl);
void ResetDefLoc(RegLocation rl);
void ResetDefLocWide(RegLocation rl);
void ResetDefTracking();
@@ -692,8 +707,8 @@
void MarkDirty(RegLocation loc);
void MarkInUse(RegStorage reg);
bool CheckCorePoolSanity();
- RegLocation UpdateLoc(RegLocation loc);
- RegLocation UpdateLocWide(RegLocation loc);
+ virtual RegLocation UpdateLoc(RegLocation loc);
+ virtual RegLocation UpdateLocWide(RegLocation loc);
RegLocation UpdateRawLoc(RegLocation loc);
/**
@@ -704,7 +719,7 @@
* @param update Whether the liveness information should be updated.
* @return Returns the properly typed temporary in physical register pairs.
*/
- RegLocation EvalLocWide(RegLocation loc, int reg_class, bool update);
+ virtual RegLocation EvalLocWide(RegLocation loc, int reg_class, bool update);
/**
* @brief Used to prepare a register location to receive a value.
@@ -713,7 +728,7 @@
* @param update Whether the liveness information should be updated.
* @return Returns the properly typed temporary in physical register.
*/
- RegLocation EvalLoc(RegLocation loc, int reg_class, bool update);
+ virtual RegLocation EvalLoc(RegLocation loc, int reg_class, bool update);
void CountRefs(RefCounts* core_counts, RefCounts* fp_counts, size_t num_regs);
void DumpCounts(const RefCounts* arr, int size, const char* msg);
@@ -729,7 +744,7 @@
bool HandleEasyDivRem(Instruction::Code dalvik_opcode, bool is_div,
RegLocation rl_src, RegLocation rl_dest, int lit);
bool HandleEasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit);
- void HandleSlowPaths();
+ virtual void HandleSlowPaths();
void GenBarrier();
void GenDivZeroException();
// c_code holds condition code that's generated from testing divisor against 0.
@@ -783,8 +798,8 @@
template <size_t pointer_size>
void GenConversionCall(ThreadOffset<pointer_size> func_offset, RegLocation rl_dest,
RegLocation rl_src);
- void GenSuspendTest(int opt_flags);
- void GenSuspendTestAndBranch(int opt_flags, LIR* target);
+ virtual void GenSuspendTest(int opt_flags);
+ virtual void GenSuspendTestAndBranch(int opt_flags, LIR* target);
// This will be overridden by x86 implementation.
virtual void GenConstWide(RegLocation rl_dest, int64_t value);
@@ -914,41 +929,41 @@
// Shared by all targets - implemented in gen_loadstore.cc.
RegLocation LoadCurrMethod();
void LoadCurrMethodDirect(RegStorage r_tgt);
- LIR* LoadConstant(RegStorage r_dest, int value);
+ virtual LIR* LoadConstant(RegStorage r_dest, int value);
// Natural word size.
- LIR* LoadWordDisp(RegStorage r_base, int displacement, RegStorage r_dest) {
+ virtual LIR* LoadWordDisp(RegStorage r_base, int displacement, RegStorage r_dest) {
return LoadBaseDisp(r_base, displacement, r_dest, kWord);
}
// Load 32 bits, regardless of target.
- LIR* Load32Disp(RegStorage r_base, int displacement, RegStorage r_dest) {
+ virtual LIR* Load32Disp(RegStorage r_base, int displacement, RegStorage r_dest) {
return LoadBaseDisp(r_base, displacement, r_dest, k32);
}
// Load a reference at base + displacement and decompress into register.
- LIR* LoadRefDisp(RegStorage r_base, int displacement, RegStorage r_dest) {
+ virtual LIR* LoadRefDisp(RegStorage r_base, int displacement, RegStorage r_dest) {
return LoadBaseDisp(r_base, displacement, r_dest, kReference);
}
// Load Dalvik value with 32-bit memory storage. If compressed object reference, decompress.
- RegLocation LoadValue(RegLocation rl_src, RegisterClass op_kind);
+ virtual RegLocation LoadValue(RegLocation rl_src, RegisterClass op_kind);
// Load Dalvik value with 64-bit memory storage.
- RegLocation LoadValueWide(RegLocation rl_src, RegisterClass op_kind);
+ virtual RegLocation LoadValueWide(RegLocation rl_src, RegisterClass op_kind);
// Load Dalvik value with 32-bit memory storage. If compressed object reference, decompress.
- void LoadValueDirect(RegLocation rl_src, RegStorage r_dest);
+ virtual void LoadValueDirect(RegLocation rl_src, RegStorage r_dest);
// Load Dalvik value with 32-bit memory storage. If compressed object reference, decompress.
- void LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest);
+ virtual void LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest);
// Load Dalvik value with 64-bit memory storage.
- void LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest);
+ virtual void LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest);
// Load Dalvik value with 64-bit memory storage.
- void LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest);
+ virtual void LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest);
// Store an item of natural word size.
- LIR* StoreWordDisp(RegStorage r_base, int displacement, RegStorage r_src) {
+ virtual LIR* StoreWordDisp(RegStorage r_base, int displacement, RegStorage r_src) {
return StoreBaseDisp(r_base, displacement, r_src, kWord);
}
// Store an uncompressed reference into a compressed 32-bit container.
- LIR* StoreRefDisp(RegStorage r_base, int displacement, RegStorage r_src) {
+ virtual LIR* StoreRefDisp(RegStorage r_base, int displacement, RegStorage r_src) {
return StoreBaseDisp(r_base, displacement, r_src, kReference);
}
// Store 32 bits, regardless of target.
- LIR* Store32Disp(RegStorage r_base, int displacement, RegStorage r_src) {
+ virtual LIR* Store32Disp(RegStorage r_base, int displacement, RegStorage r_src) {
return StoreBaseDisp(r_base, displacement, r_src, k32);
}
@@ -957,7 +972,7 @@
* @param rl_dest The destination dalvik register location.
* @param rl_src The source register location. Can be either physical register or dalvik register.
*/
- void StoreValue(RegLocation rl_dest, RegLocation rl_src);
+ virtual void StoreValue(RegLocation rl_dest, RegLocation rl_src);
/**
* @brief Used to do the final store in a wide destination as per bytecode semantics.
@@ -966,7 +981,7 @@
* @param rl_src The source register location. Can be either physical register or dalvik
* register.
*/
- void StoreValueWide(RegLocation rl_dest, RegLocation rl_src);
+ virtual void StoreValueWide(RegLocation rl_dest, RegLocation rl_src);
/**
* @brief Used to do the final store to a destination as per bytecode semantics.
@@ -978,7 +993,7 @@
* register value that now needs to be properly registered. This is used to avoid an
* extra register copy that would result if StoreValue was called.
*/
- void StoreFinalValue(RegLocation rl_dest, RegLocation rl_src);
+ virtual void StoreFinalValue(RegLocation rl_dest, RegLocation rl_src);
/**
* @brief Used to do the final store in a wide destination as per bytecode semantics.
@@ -990,14 +1005,14 @@
* register values that now need to be properly registered. This is used to avoid an
* extra pair of register copies that would result if StoreValueWide was called.
*/
- void StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src);
+ virtual void StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src);
// Shared by all targets - implemented in mir_to_lir.cc.
void CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list);
- void HandleExtendedMethodMIR(BasicBlock* bb, MIR* mir);
+ virtual void HandleExtendedMethodMIR(BasicBlock* bb, MIR* mir);
bool MethodBlockCodeGen(BasicBlock* bb);
bool SpecialMIR2LIR(const InlineMethod& special);
- void MethodMIR2LIR();
+ virtual void MethodMIR2LIR();
// Update LIR for verbose listings.
void UpdateLIROffsets();
@@ -1345,14 +1360,14 @@
* @param loc location of result
* @returns update location
*/
- RegLocation ForceTemp(RegLocation loc);
+ virtual RegLocation ForceTemp(RegLocation loc);
/*
* @brief Force a wide location (in registers) into temporary registers
* @param loc location of result
* @returns update location
*/
- RegLocation ForceTempWide(RegLocation loc);
+ virtual RegLocation ForceTempWide(RegLocation loc);
static constexpr OpSize LoadStoreOpSize(bool wide, bool ref) {
return wide ? k64 : ref ? kReference : k32;
@@ -1398,7 +1413,7 @@
*/
virtual bool GenSpecialCase(BasicBlock* bb, MIR* mir, const InlineMethod& special);
- private:
+ protected:
void ClobberBody(RegisterInfo* p);
void SetCurrentDexPc(DexOffset dexpc) {
current_dalvik_offset_ = dexpc;
@@ -1457,7 +1472,14 @@
// Copy arg0 and arg1 to kArg0 and kArg1 safely, possibly using
// kArg2 as temp.
- void CopyToArgumentRegs(RegStorage arg0, RegStorage arg1);
+ virtual void CopyToArgumentRegs(RegStorage arg0, RegStorage arg1);
+
+ /**
+ * @brief Load Constant into RegLocation
+ * @param rl_dest Destination RegLocation
+ * @param value Constant value
+ */
+ virtual void GenConst(RegLocation rl_dest, int value);
public:
// TODO: add accessors for these.