From 8811335c6c4347157b368600a363c4bc9dc8f880 Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Mon, 12 May 2008 17:24:41 +0000 Subject: [PATCH] Increase propagation of POINTER and SAFE function memory types. --- SMPInstr.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++---- SMPInstr.h | 1 + 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 038e0167..04a6d9d3 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -1057,12 +1057,66 @@ void SMPInstr::MDFixupDefUseLists(void) { #endif if (DebugFlag) { - msg("DEBUG after MDFixupDefuseLists:\n"); + msg("DEBUG after MDFixupDefUseLists:\n"); this->Dump(); } return; } // end of SMPInstr::MDFixupDefUseLists() +// If we can definitely identify which part of the addressing expression +// used in MemOp is the POINTER type, and it is not a STACKPTR or GLOBALPTR +// immediate, set the USE type for that register to POINTER and return true. +bool SMPInstr::MDFindPointerUse(op_t MemOp, bool UseFP) { + bool changed = false; + int BaseReg; + int IndexReg; + ushort ScaleFactor; + ea_t offset; + set<DefOrUse, LessDefUse>::iterator UseIter; + + if (NN_lea == this->SMPcmd.itype) + return false; // lea instruction really has no memory operands + if (NN_fnop == this->SMPcmd.itype) + return false; // SSA marker instruction + + MDExtractAddressFields(MemOp, BaseReg, IndexReg, ScaleFactor, offset); + if ((R_sp == BaseReg) || (R_sp == IndexReg)) + return false; // stack accesses will get STACKPTR type in SetImmedTypes() + if (UseFP && ((R_bp == BaseReg) || (R_bp == IndexReg))) + return false; + if (IsImmedGlobalAddress(offset)) + return false; // handled in SetImmedTypes() + + // At this point, we must have a base address in a register. + if ((0 < ScaleFactor) || (R_none == IndexReg)) { + // IndexReg is scaled, meaning it is NUMERIC, so BaseReg must + // be a POINTER, or IndexReg is not present, so BaseReg is the + // only possible holder of an address. + if (R_none != BaseReg) { + changed = true; + op_t BaseOp; + BaseOp.type = o_reg; + BaseOp.reg = MDCanonicalizeSubReg(BaseReg); + UseIter = this->SetUseType(BaseOp, POINTER); + assert(UseIter != this->GetLastUse()); + } + } + else if (R_none == BaseReg) { + // We have an unscaled IndexReg and no BaseReg and offset was + // not a global offset, so IndexReg must be a POINTER. + if (R_none != IndexReg) { + changed = true; + op_t IndexOp; + IndexOp.type = o_reg; + IndexOp.reg = MDCanonicalizeSubReg(IndexReg); + UseIter = this->SetUseType(IndexOp, POINTER); + assert(UseIter != this->GetLastUse()); + } + } + + return changed; +} // end of SMPInstr::MDFindPointerUse() + // Set the type of all immediate operands found in the USE set. // Set all flags and floating point register USEs and DEFs to NUMERIC also. void SMPInstr::SetImmedTypes(bool UseFP) { @@ -1122,6 +1176,11 @@ void SMPInstr::SetImmedTypes(bool UseFP) { if (DebugFlag) msg("Setting floating point reg to NUMERIC\n"); CurrUse = this->SetUseType(UseOp, NUMERIC); } + else if ((o_mem == UseOp.type) || (o_phrase == UseOp.type) || (o_displ == UseOp.type)) { + // For memory operands, we need to identify the POINTER value that + // is used in the addressing mode, if possible. + (void) this->MDFindPointerUse(UseOp, UseFP); + } ++CurrUse; } // end while all USEs via CurrUse @@ -1160,6 +1219,11 @@ void SMPInstr::SetImmedTypes(bool UseFP) { CurrDef = this->SetDefType(DefOp, NUMERIC); } #endif + else if ((o_mem == DefOp.type) || (o_phrase == DefOp.type) || (o_displ == DefOp.type)) { + // For memory operands, we need to identify the POINTER value that + // is used in the addressing mode, if possible. + (void) this->MDFindPointerUse(DefOp, UseFP); + } ++CurrDef; } // end while all DEFs via CurrDef return; @@ -1239,7 +1303,8 @@ bool SMPInstr::InferTypes(void) { changed = true; // Be conservative and only propagate register DEFs. We can improve // this in the future. **!!** - if (o_reg == DefOp.type) { + if ((o_reg == DefOp.type) + || (FUNC_SAFE == this->BasicBlock->GetFunc()->GetReturnAddressStatus())) { if (this->BasicBlock->IsLocalName(DefOp)) { (void) this->BasicBlock->PropagateLocalDefType(DefOp, NUMERIC, this->GetAddr()); @@ -1277,7 +1342,8 @@ bool SMPInstr::InferTypes(void) { CurrDef = this->SetDefType(DefOp, CurrUse->GetType()); // Be conservative and only propagate register DEFs. We can improve // this in the future. **!!** - if (o_reg == DefOp.type) { + if ((o_reg == DefOp.type) + || (FUNC_SAFE == this->BasicBlock->GetFunc()->GetReturnAddressStatus())) { if (this->BasicBlock->IsLocalName(DefOp)) { (void) this->BasicBlock->PropagateLocalDefType(DefOp, CurrUse->GetType(), this->GetAddr()); @@ -1305,7 +1371,8 @@ bool SMPInstr::InferTypes(void) { changed = true; // Be conservative and only propagate register DEFs. We can improve // this in the future. **!!** - if (o_reg == DefOp.type) { + if ((o_reg == DefOp.type) + || (FUNC_SAFE == this->BasicBlock->GetFunc()->GetReturnAddressStatus())) { if (this->BasicBlock->IsLocalName(DefOp)) { (void) this->BasicBlock->PropagateLocalDefType(DefOp, POINTER, this->GetAddr()); @@ -1849,7 +1916,8 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { if (!MDIsIndirectMemoryOpnd(DefOp, this->BasicBlock->GetFunc()->UsesFramePointer())) { // Be conservative and only propagate register DEFs. We can improve // this in the future. **!!** - if (o_reg == DefOp.type) { + if ((o_reg == DefOp.type) + || (FUNC_SAFE == this->BasicBlock->GetFunc()->GetReturnAddressStatus())) { if (this->BasicBlock->IsLocalName(DefOp)) { (void) this->BasicBlock->PropagateLocalDefType(DefOp, LeftType, this->GetAddr()); diff --git a/SMPInstr.h b/SMPInstr.h index a51a6622..7c9b4471 100644 --- a/SMPInstr.h +++ b/SMPInstr.h @@ -262,6 +262,7 @@ private: void MDAddRegDef(ushort, bool); // Add DEF of register if not already a DEF void MDAddRegUse(ushort, bool); // Add USE of register if not already a USE void MDAnnotateSIBStackConstants(FILE *, op_t, ea_t, bool); // Handle x86 opcode SIB byte + bool MDFindPointerUse(op_t MemOp, bool UseFP); // Set base reg to POINTER bool BuildUnaryRTL(SMPoperator UnaryOp); // helper for BuildRTL() bool BuildUnary2OpndRTL(SMPoperator UnaryOp); // helper for BuildRTL() bool BuildBinaryRTL(SMPoperator BinaryOp); // helper for BuildRTL() -- GitLab