#pragma once #include "Array.h" #include "NumberSet.h" #include "Errors.h" #include "BitVector.h" #include #include "MachineTypes.h" #include "Ident.h" #include "Linker.h" class Declaration; enum InterCode { IC_NONE, IC_LOAD_TEMPORARY, IC_BINARY_OPERATOR, IC_UNARY_OPERATOR, IC_RELATIONAL_OPERATOR, IC_CONVERSION_OPERATOR, IC_STORE, // store src[0] into src[1] IC_LOAD, // load from src[0] IC_LEA, IC_COPY, // Copy from src[0] to src[1] IC_STRCPY, IC_MALLOC, IC_FREE, IC_TYPECAST, IC_CONSTANT, IC_BRANCH, IC_JUMP, IC_PUSH_FRAME, IC_POP_FRAME, IC_CALL, IC_CALL_NATIVE, IC_RETURN_VALUE, IC_RETURN_STRUCT, IC_RETURN, IC_ASSEMBLER, IC_JUMPF, IC_SELECT, IC_DISPATCH, IC_UNREACHABLE }; enum InterType { IT_NONE, IT_BOOL, IT_INT8, IT_INT16, IT_INT32, IT_FLOAT, IT_POINTER }; extern int InterTypeSize[]; enum InterMemory { IM_NONE, IM_PARAM, // Memory used to access parameters on stack IM_LOCAL, IM_GLOBAL, IM_FRAME, // Memory used to pass parameters on stack IM_PROCEDURE, IM_INDIRECT, IM_TEMPORARY, IM_ABSOLUTE, IM_FPARAM, // Memory used to access parameters in zp IM_FFRAME, // Memory used to pass parameters in zp }; enum InterOperator { IA_NONE, IA_ADD, IA_SUB, IA_MUL, IA_DIVU, IA_DIVS, IA_MODU, IA_MODS, IA_OR, IA_AND, IA_XOR, IA_NEG, IA_ABS, IA_FLOOR, IA_CEIL, IA_NOT, IA_SHL, IA_SHR, IA_SAR, IA_CMPEQ, IA_CMPNE, IA_CMPGES, IA_CMPLES, IA_CMPGS, IA_CMPLS, IA_CMPGEU, IA_CMPLEU, IA_CMPGU, IA_CMPLU, IA_FLOAT2INT, IA_INT2FLOAT, IA_FLOAT2UINT, IA_UINT2FLOAT, IA_EXT8TO16U, IA_EXT8TO32U, IA_EXT16TO32U, IA_EXT8TO16S, IA_EXT8TO32S, IA_EXT16TO32S }; class InterInstruction; class InterCodeBasicBlock; class InterCodeProcedure; class InterVariable; class InterCodeModule; typedef InterInstruction* InterInstructionPtr; typedef InterCodeBasicBlock* InterCodeBasicBlockPtr; typedef InterCodeProcedure* InterCodeProcedurePtr; typedef GrowingArray GrowingTypeArray; typedef GrowingArray GrowingIntArray; typedef GrowingArray GrowingInstructionPtrArray; typedef GrowingArray GrowingInterCodeBasicBlockPtrArray; typedef GrowingArray GrowingInstructionArray; typedef GrowingArray GrowingInterCodeProcedurePtrArray; typedef GrowingArray GrowingVariableArray; #define INVALID_TEMPORARY (-1) InterOperator MirrorRelational(InterOperator oper); InterOperator InvertRelational(InterOperator oper); class IntegerValueRange { public: IntegerValueRange(void); ~IntegerValueRange(void); void Reset(void); void Restart(void); int64 mMinValue, mMaxValue; uint8 mMinExpanded, mMaxExpanded; enum State : uint8 { S_UNKNOWN, S_UNBOUND, S_WEAK, S_BOUND } mMinState, mMaxState; bool Same(const IntegerValueRange& range) const; bool Merge(const IntegerValueRange& range, bool head, bool initial); void Expand(const IntegerValueRange& range); void Union(const IntegerValueRange& range); void Limit(const IntegerValueRange& range); void MergeUnknown(const IntegerValueRange& range); void SetLimit(int64 minValue, int64 maxValue); bool IsConstant(void) const; void LimitMin(int64 value); void LimitMax(int64 value); void LimitMinBound(int64 value); void LimitMaxBound(int64 value); void LimitMinWeak(int64 value); void LimitMaxWeak(int64 value); }; typedef GrowingArray GrowingIntegerValueRangeArray; class ValueSet { protected: InterInstructionPtr * mInstructions; int mNum, mSize; public: ValueSet(void); ValueSet(const ValueSet& values); ~ValueSet(void); ValueSet& operator=(const ValueSet& values); void FlushAll(void); void FlushCallAliases(const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams); void FlushFrameAliases(void); void RemoveValue(int index); void InsertValue(InterInstruction * ins); void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); void Intersect(ValueSet& set); }; class TempForwardingTable { protected: struct Assoc { int mAssoc, mSucc, mPred; Assoc(void) {} Assoc(int assoc, int succ, int pred) { this->mAssoc = assoc; this->mSucc = succ; this->mPred = pred; } Assoc(const Assoc& assoc) { this->mAssoc = assoc.mAssoc; this->mSucc = assoc.mSucc; this->mPred = assoc.mPred; } }; GrowingArray mAssoc; public: TempForwardingTable(void); TempForwardingTable(const TempForwardingTable& table); TempForwardingTable& operator=(const TempForwardingTable& table); void Intersect(const TempForwardingTable& table); int Size(void) const; void SetSize(int size); void Reset(void); void Shrink(void); int operator[](int n); void Destroy(int n); void Build(int from, int to); }; class InterVariable { public: bool mUsed, mAliased, mTemp, mNotAliased; int mIndex, mSize, mOffset, mTempIndex, mByteIndex; int mNumReferences; const Ident * mIdent; LinkerObject * mLinkerObject; Declaration * mDeclaration; InterVariable(void) : mUsed(false), mAliased(false), mTemp(false), mNotAliased(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr), mTempIndex(-1), mDeclaration(nullptr) { } }; class InterOperand { public: int mTemp; InterType mType; bool mFinal; int64 mIntConst; double mFloatConst; int mVarIndex, mOperandSize, mStride, mRestricted; LinkerObject * mLinkerObject; InterMemory mMemory, mMemoryBase; IntegerValueRange mRange; void Forward(const InterOperand& op); void ForwardTemp(const InterOperand& op); void ForwardMem(const InterOperand& op); InterOperand(void); bool IsEqual(const InterOperand & op) const; bool IsUByte(void) const; bool IsSByte(void) const; bool IsUnsigned(void) const; bool IsPositive(void) const; bool IsInRange(int lower, int upper) const; bool IsNotUByte(void) const; void Disassemble(FILE* file, InterCodeProcedure* proc); }; class InterInstruction { public: Location mLocation; InterCode mCode; InterOperand mSrc[8]; InterOperand mDst; InterOperand mConst; InterOperator mOperator; int mNumOperands; bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr, mRemove; InterInstruction(const Location& loc, InterCode code); bool IsEqual(const InterInstruction* ins) const; bool IsEqualSource(const InterInstruction* ins) const; InterInstruction* Clone(void) const; bool ReferencesTemp(int temp) const; bool UsesTemp(int temp) const; int NumUsedTemps(void) const; void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int& nlocals, int& nparams); void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps); void FilterVarsUsage(const GrowingVariableArray& localVars, NumberSet& requiredVars, NumberSet& providedVars, const GrowingVariableArray& params, NumberSet& requiredParams, NumberSet& providedParams, InterMemory paramMemory); void FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars); void FilterStaticVarsByteUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars, Errors * errors); bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps); bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory); bool RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock * block, const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns); bool RemoveUnusedStaticStoreByteInstructions(InterCodeBasicBlock* block, const GrowingVariableArray& staticVars, NumberSet& requiredVars); void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps); void LocalRenameRegister(GrowingIntArray& renameTable, int& num); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void PerformTempForwarding(TempForwardingTable& forwardingTable, bool reverse); bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets); void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void CollectActiveTemporaries(FastNumberSet& set); void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries); void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray& localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes); void SimpleLocalToTemp(int vindex, int temp); bool ConstantFolding(void); bool ConstantFoldingRelationRange(void); void UnionRanges(InterInstruction* ins); void Disassemble(FILE* file, InterCodeProcedure * proc); }; class InterCodeBasicBlock { public: InterCodeProcedure * mProc; int mIndex, mNumEntries, mNumEntered, mTraceIndex; InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator; GrowingInstructionArray mInstructions; bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid; NumberSet mLocalUsedTemps, mLocalModifiedTemps; NumberSet mLocalRequiredTemps, mLocalProvidedTemps; NumberSet mEntryRequiredTemps, mEntryProvidedTemps, mEntryPotentialTemps; NumberSet mExitRequiredTemps, mExitProvidedTemps, mExitPotentialTemps; NumberSet mEntryConstTemp, mExitConstTemp; NumberSet mNewRequiredTemps; NumberSet mLocalRequiredVars, mLocalProvidedVars; NumberSet mEntryRequiredVars, mEntryProvidedVars; NumberSet mExitRequiredVars, mExitProvidedVars; NumberSet mLocalRequiredStatics, mLocalProvidedStatics; NumberSet mEntryRequiredStatics, mEntryProvidedStatics; NumberSet mExitRequiredStatics, mExitProvidedStatics; NumberSet mLocalRequiredParams, mLocalProvidedParams; NumberSet mEntryRequiredParams, mEntryProvidedParams; NumberSet mExitRequiredParams, mExitProvidedParams; GrowingInstructionArray mLoadStoreInstructions; GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange; GrowingIntegerValueRangeArray mEntryParamValueRange, mTrueParamValueRange, mFalseParamValueRange, mLocalParamValueRange; GrowingArray mMemoryValueSize, mEntryMemoryValueSize; ExpandingArray mEntryBlocks, mLoopPathBlocks; GrowingInstructionPtrArray mMergeTValues, mMergeAValues; ValueSet mMergeValues; TempForwardingTable mMergeForwardingTable; InterCodeBasicBlock(InterCodeProcedure * proc); ~InterCodeBasicBlock(void); InterCodeBasicBlock* Clone(void); void Append(InterInstruction * code); const InterInstruction* FindByDst(int dst) const; void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump); void CollectEntries(void); void CollectEntryBlocks(InterCodeBasicBlock* from); void GenerateTraces(bool expand, bool compact); void BuildDominatorTree(InterCodeBasicBlock * from); bool MergeSameConditionTraces(void); void LocalToTemp(int vindex, int temp); void CollectAllUsedDefinedTemps(NumberSet& defined, NumberSet& used); void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int & nlocals, int & nparams); void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams); void RecheckLocalAliased(void); void CollectLocalUsedTemps(int numTemps); bool PropagateNonLocalUsedConstTemps(void); void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps); bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps); bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars, const NumberSet & aliasedLocals, const NumberSet & aliasedParams); void BuildLocalTempSets(int num); void BuildGlobalProvidedTempSet(const NumberSet & fromProvidedTemps, const NumberSet& potentialProvidedTemps); bool BuildGlobalRequiredTempSet(NumberSet& fromRequiredTemps); bool RemoveUnusedResultInstructions(void); void BuildCallerSaveTempSet(NumberSet& callerSaveTemps); void BuildConstTempSets(void); bool PropagateConstOperationsUp(void); bool RemoveUnusedLocalStoreInstructions(void); void BuildLocalVariableSets(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory); void BuildGlobalProvidedVariableSet(const GrowingVariableArray& localVars, NumberSet fromProvidedVars, const GrowingVariableArray& params, NumberSet fromProvidedParams, InterMemory paramMemory); bool BuildGlobalRequiredVariableSet(const GrowingVariableArray& localVars, NumberSet& fromRequiredVars, const GrowingVariableArray& params, NumberSet& fromRequiredParams, InterMemory paramMemory); bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, const GrowingVariableArray& params, InterMemory paramMemory); bool RemoveUnusedIndirectStoreInstructions(void); void BuildStaticVariableSet(const GrowingVariableArray& staticVars); void BuildGlobalProvidedStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet fromProvidedVars); bool BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars); bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars); void BuildStaticVariableByteSet(const GrowingVariableArray& staticVars, int bsize); bool RemoveUnusedStaticStoreByteInstructions(const GrowingVariableArray& staticVars, int bsize); bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop); void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); bool BuildGlobalIntegerRangeSets(bool initial, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void SimplifyIntegerRangeRelops(void); void MarkIntegerRangeBoundUp(int temp, int64 value, GrowingIntegerValueRangeArray& range); void UnionIntegerRanges(const InterCodeBasicBlock* block); void PruneUnusedIntegerRangeSets(void); bool CombineIndirectAddressing(void); void WarnUnreachable(void); GrowingIntArray mEntryRenameTable; GrowingIntArray mExitRenameTable; void LinkerObjectForwarding(const GrowingInstructionPtrArray& tvalue); bool LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars); void ReduceRecursionTempSpilling(InterMemory paramMemory, const GrowingInstructionPtrArray& tvalue); void LocalRenameRegister(const GrowingIntArray& renameTable, int& num); void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void RenameValueRanges(const GrowingIntArray& renameTable, int numTemps); void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle); void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse, bool checkloops); void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, FastNumberSet& fsingle); bool EliminateDeadBranches(void); bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue); bool SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps); bool SimplifyPointerOffsets(void); bool EliminateAliasValues(const GrowingInstructionPtrArray& tvalue, const GrowingInstructionPtrArray& avalue); bool ForwardShortLoadStoreOffsets(void); void CalculateSingleUsedTemps(FastNumberSet& fused, FastNumberSet& fsingle); bool CalculateSingleAssignmentTemps(FastNumberSet& tassigned, GrowingInstructionPtrArray& tvalue, NumberSet& modifiedParams, InterMemory paramMemory); bool SingleAssignmentTempForwarding(const GrowingInstructionPtrArray& tunified, const GrowingInstructionPtrArray& tvalues); void BuildCollisionTable(NumberSet* collisionSets); void ReduceTemporaries(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void CollectSimpleLocals(FastNumberSet& complexLocals, FastNumberSet& simpleLocals, GrowingTypeArray & localTypes, FastNumberSet& complexParams, FastNumberSet& simpleParams, GrowingTypeArray& paramTypes); void SimpleLocalToTemp(int vindex, int temp); void CollectActiveTemporaries(FastNumberSet& set); void ShrinkActiveTemporaries(FastNumberSet& set, GrowingTypeArray& temporaries); void RemapActiveTemporaries(const FastNumberSet& set); void Disassemble(FILE* file, bool dumpSets); void CollectVariables(GrowingVariableArray & globalVars, GrowingVariableArray & localVars, GrowingVariableArray& paramVars, InterMemory paramMemory); void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars); void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall); bool RecheckOuterFrame(void); bool IsLeafProcedure(void); bool PreventsCallerStaticStack(void); bool ForwardDiamondMovedTemp(void); bool ForwardLoopMovedTemp(void); bool MoveTrainCrossBlock(void); bool HoistCommonConditionalPath(void); bool IsDirectDominatorBlock(InterCodeBasicBlock* block); void MarkRelevantStatics(void); void RemoveNonRelevantStatics(void); bool IsTempModifiedOnPath(int temp, int at) const; bool IsTempReferencedOnPath(int temp, int at) const; bool DestroyingMem(const InterInstruction* lins, const InterInstruction* sins) const; bool DestroyingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const; bool CollidingMem(const InterInstruction* ins1, const InterInstruction* ins2) const; bool CollidingMem(const InterOperand& op, InterType type, const InterInstruction* ins) const; bool CollidingMem(const InterOperand& op1, InterType type1, const InterOperand& op2, InterType type2) const; bool CollidingMem(InterCodeBasicBlock* block, InterInstruction* lins, int from, int to) const; bool PushSinglePathResultInstructions(void); bool CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const; bool CanMoveInstructionBeforeBlock(int ii) const; bool CanMoveInstructionBeforeBlock(int ii, const InterInstruction * ins) const; bool CanMoveInstructionBehindBlock(int ii) const; bool CanMoveInstructionDown(int si, int ti) const; int FindSameInstruction(const InterInstruction* ins) const; bool MergeCommonPathInstructions(void); bool IsTempModified(int temp); bool IsTempModifiedInRange(int from, int to, int temp); bool IsTempUsedInRange(int from, int to, int temp); bool IsTempReferenced(int temp); bool IsTempReferencedInRange(int from, int to, int temp); bool IsInsModified(const InterInstruction* ins); bool IsInsModifiedInRange(int from, int to, const InterInstruction* ins); InterInstruction* FindTempOrigin(int temp) const; bool CheapInlining(int & numTemps); void CheckFinalLocal(void); void CheckFinal(void); void CheckBlocks(void); bool IsConstExitTemp(int temp) const; bool CommonTailCodeMerge(void); bool SplitSingleBranchUseConst(void); void PeepholeOptimization(const GrowingVariableArray& staticVars); bool PeepholeReplaceOptimization(const GrowingVariableArray& staticVars); bool MoveLoopHeadCheckToTail(void); void SingleBlockLoopOptimisation(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); void SingleBlockLoopUnrolling(void); bool SingleBlockLoopPointerSplit(int& spareTemps); bool SingleBlockLoopPointerToByte(int& spareTemps); bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray & body); bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray& body); void CollectLoopPath(const ExpandingArray& body, ExpandingArray& path); void InnerLoopOptimization(const NumberSet& aliasedParams); void ConstLoopOptimization(void); void PushMoveOutOfLoop(void); bool MoveConditionOutOfLoop(void); void SingleLoopCountZeroCheck(void); void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue); void RemoveUnusedMallocs(void); bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray& body); bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); bool MergeLoopTails(void); InterCodeBasicBlock* BuildLoopPrefix(void); void BuildLoopSuffix(void); void ExpandSelect(void); void SplitBranches(void); void FollowJumps(void); bool IsEqual(const InterCodeBasicBlock* block) const; void CompactInstructions(void); bool OptimizeIntervalCompare(void); bool DropUnreachable(void); bool CheckStaticStack(void); void ApplyStaticStack(InterOperand& iop, const GrowingVariableArray& localVars); void CollectStaticStack(LinkerObject * lobj, const GrowingVariableArray& localVars); void PromoteStaticStackParams(LinkerObject* paramlobj); bool SameExitCode(const InterCodeBasicBlock* block) const; void WarnUsedUndefinedVariables(void); void CheckValueReturn(void); void CheckNullptrDereference(void); void CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool & storesIndirect, bool & loadsIndirect, bool & globalsChecked); }; class InterCodeProcedure { friend class InterCodeBasicBlock; protected: GrowingIntArray mRenameTable, mRenameUnionTable, mGlobalRenameTable; TempForwardingTable mTempForwardingTable; GrowingInstructionPtrArray mValueForwardingTable; GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange; void ResetVisited(void); void ResetEntryBlocks(void); public: InterCodeBasicBlock * mEntryBlock; GrowingInterCodeBasicBlockPtrArray mBlocks; GrowingTypeArray mTemporaries; GrowingIntArray mTempOffset, mTempSizes; int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase, mNumRestricted; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer, mDynamicStack, mAssembled; bool mDispatchedCall; bool mCheckUnreachable; GrowingInterCodeProcedurePtrArray mCalledFunctions; bool mCheapInline; bool mNoInline; InterCodeModule * mModule; int mID; int mLocalSize, mNumLocals; GrowingVariableArray mLocalVars, mParamVars; NumberSet mLocalAliasedSet, mParamAliasedSet; Location mLocation; const Ident * mIdent, * mSection; LinkerObject * mLinkerObject, * mSaveTempsLinkerObject; Declaration * mDeclaration; InterType mReturnType; uint64 mCompilerOptions; bool mLoadsIndirect, mStoresIndirect, mGlobalsChecked; NumberSet mReferencedGlobals, mModifiedGlobals; InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject); ~InterCodeProcedure(void); int AddTemporary(InterType type); int AddRestricted(void); void Close(void); // void Set(InterCodeIDMapper* mapper, BitVector localStructure, Scanner scanner, bool debug); void AddCalledFunction(InterCodeProcedure* proc); void CallsFunctionPointer(void); void MarkRelevantStatics(void); void RemoveNonRelevantStatics(void); void MapCallerSavedTemps(void); bool ReferencesGlobal(int varindex); bool ModifiesGlobal(int varindex); void MapVariables(void); void ReduceTemporaries(void); void Disassemble(FILE* file); void Disassemble(const char* name, bool dumpSets = false); protected: void BuildLocalAliasTable(void); void BuildTraces(bool expand, bool dominators = true, bool compact = false); void BuildDataFlowSets(void); void RenameTemporaries(void); void TempForwarding(bool reverse = false, bool checkloops = false); void RemoveUnusedInstructions(void); bool GlobalConstantPropagation(void); bool PropagateNonLocalUsedTemps(void); void BuildLoopPrefix(void); void SingleAssignmentForwarding(void); void RemoveUnusedStoreInstructions(InterMemory paramMemory); void RemoveUnusedPartialStoreInstructions(void); void RemoveUnusedLocalStoreInstructions(void); void MergeCommonPathInstructions(void); void PushSinglePathResultInstructions(void); void CollectVariables(InterMemory paramMemory); void PromoteSimpleLocalsToTemp(InterMemory paramMemory, int nlocals, int nparams); void SimplifyIntegerNumeric(FastNumberSet& activeSet); void SingleBlockLoopPointerSplit(FastNumberSet& activeSet); void SingleBlockLoopPointerToByte(FastNumberSet& activeSet); void MergeIndexedLoadStore(void); void EliminateAliasValues(); void LoadStoreForwarding(InterMemory paramMemory); void ReduceRecursionTempSpilling(InterMemory paramMemory); void ExpandSelect(void); void PropagateConstOperationsUp(void); void RebuildIntegerRangeSet(void); void CombineIndirectAddressing(void); void SingleTailLoopOptimization(InterMemory paramMemory); void HoistCommonConditionalPath(void); void RemoveUnusedMallocs(void); void RecheckLocalAliased(void); void ConstLoopOptimization(void); void MergeBasicBlocks(void); void CheckUsedDefinedTemps(void); void WarnUsedUndefinedVariables(void); void PropagateMemoryAliasingInfo(void); void MoveConditionsOutOfLoop(void); void PeepholeOptimization(void); void CheckFinal(void); void CheckBlocks(void); void DisassembleDebug(const char* name); }; class InterCodeModule { public: InterCodeModule(Errors* errors, Linker * linker); ~InterCodeModule(void); void InitParamStack(LinkerSection * stackSection); bool Disassemble(const char* name); GrowingInterCodeProcedurePtrArray mProcedures; GrowingVariableArray mGlobalVars; LinkerObject * mParamLinkerObject; LinkerSection * mParamLinkerSection; Linker * mLinker; Errors* mErrors; uint64 mCompilerOptions; };