diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c')
-rw-r--r-- | compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c | 2736 |
1 files changed, 2736 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c b/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c new file mode 100644 index 0000000..dad9501 --- /dev/null +++ b/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c @@ -0,0 +1,2736 @@ +#include "IroPointerAnalysis.h" +#include "IroMalloc.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/CParser.h" +#include "compiler/objects.h" +#include "compiler/types.h" + +// TODO: this should really be elsewhere (but where?) +CW_INLINE UInt32 gcd(UInt32 a, UInt32 b) { + UInt32 chk; + + if (!a) + return b; + if (!b) + return a; + + while (1) { + chk = a % b; + if (!chk) + return b; + a = b; + b = chk; + } +} + +// #define IRO_DEBUG + +typedef struct ExtendedParamSet ExtendedParamSet; +typedef struct LocationSet LocationSet; +typedef struct LocationSetSet LocationSetSet; +typedef struct ObjectSet ObjectSet; +typedef struct PAHeapBlock PAHeapBlock; +typedef struct PALocalVar PALocalVar; +typedef struct PAMemoryBlock PAMemoryBlock; +typedef struct ParamMapping ParamMapping; +typedef struct ParamMappingFunction ParamMappingFunction; +typedef struct PartialTransferFunction PartialTransferFunction; +typedef struct PointsToEntry PointsToEntry; +// typedef struct PointsToFunction PointsToFunction; +typedef struct Stack Stack; +typedef struct StackElement StackElement; + +typedef UInt32 uint32; + +void __assertion_failed(char *expr, char *filename, int line); + +#ifdef IRO_DEBUG +#define IRO_ASSERT(line, expr) \ + do { \ + if (!(expr)) { \ + __assertion_failed(#expr, __FILE__, line); \ + } \ + } while (0); + +#define IRO_DEBUG_CLEAR(obj, type) \ + memset((obj), 0xFF, sizeof(type)) +#else +#define IRO_ASSERT(line, expr) ((void) 0) +#define IRO_DEBUG_CLEAR(obj, type) ((void) 0) +#endif + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct StackElement { + Object *proc; + PartialTransferFunction *ptf; + ParamMappingFunction *map; + IROLinear *funcCall; +}; + +struct Stack { + StackElement *top; + Stack *next; +}; + +struct ObjectSet { + Object *proc; + ObjectSet *otherProcs; +}; + +struct ExtendedParam { + ObjectSet *objectSet; + uint32 x4; +}; + +struct ExtendedParamSet { + ExtendedParam *ep; + ExtendedParamSet *otherEps; +}; + +struct PAHeapBlock { + IROLinear *x0; +}; + +struct PALocalVar { + Object *x0; + char *x4; +}; + +typedef enum { + PAMEMORYBLOCKKIND_INVALID, + PAMEMORYBLOCKKIND_1, + PAMEMORYBLOCKKIND_EXTENDEDPARAM, + PAMEMORYBLOCKKIND_LOCALVAR, + PAMEMORYBLOCKKIND_HEAPBLOCK, + PAMEMORYBLOCKKIND_INT, + PAMEMORYBLOCKKIND_6 +} PAMemoryBlockKind; + +struct PAMemoryBlock { + PAMemoryBlockKind kind; + union { + ExtendedParam *ep; + PALocalVar *localvar; + PAHeapBlock *heapblock; + CInt64 intval; + void *x6; + } u; +}; + +struct LocationSet { + PAMemoryBlock *block; + Type *rtype; + union { + struct { + CInt64 field; + UInt32 stride; + } known; + struct { + PAMemoryBlock *restriction; + LocationSet *bitfieldOf; + } unknown; + } u; +}; + +struct LocationSetSet { + LocationSet *loc; + LocationSetSet *otherLocs; + UInt8 count; +}; + +struct ParamMapping { + IROLinear *actual; + Object *formal; + ExtendedParam *extended; +}; + +struct ParamMappingFunction { + ParamMapping *mapping; + ParamMappingFunction *otherMappings; +}; + +struct PointsToEntry { + LocationSet *loc; + LocationSetSet *locs; +}; + +struct PointsToFunction { + PointsToEntry *pte; + PointsToFunction *otherPtes; +}; + +struct PartialTransferFunction { + PointsToFunction *initialPointsToFn; + PointsToFunction *finalPointsToFn; + LocationSetSet *funcModifies; + LocationSet *returnLocation; + Boolean x10; + struct { + IROLinear *nd; + PartialTransferFunction *ptf; + } context; +}; + +struct PTFList { + PartialTransferFunction *ptf; + PTFList *otherPTFs; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +// TODO: how many of these are actually in IroPointerAnalysis.c? +static uint32 stExtendedParamNum; +static PartialTransferFunction *stUnknownPTF; +static uint32 stIndentationLevel; +static UInt8 stTabs[0x2C]; // unused mystery object +static Stack *stCallingContextStack; +static ObjectList *stParamObjs; +static jmp_buf stAbortPointerAnalysis; +static Object stUnknown; +static Object *stCurrentProc; +static ExtendedParamSet *stExtParamSet; +static PTFList *stPTFList; +static uint32 stMaxPassCount; +// TODO: stEvalProcActionParams +static IRONode *stExceptionFNode; + +static PAMemoryBlock stDummyMemoryBlock = { + PAMEMORYBLOCKKIND_1 +}; +static PAMemoryBlock *stUnknownMb = &stDummyMemoryBlock; + +static LocationSet stDummyLocationSet = { + &stDummyMemoryBlock +}; + +static LocationSet *stUnknownLs = &stDummyLocationSet; + +// forward decls +CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr); +CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList); +CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList); +CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src); +CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls); +CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss); +CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src); +CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf); +CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src); +CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc); +CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src); +CW_INLINE void PTFList_RemoveAll(PTFList *ptfList); + +CW_INLINE StackElement *StackElement_New(void) { + StackElement *stackElement = IRO_malloc(sizeof(StackElement)); + IRO_ASSERT(103, stackElement != NULL); +#ifdef IRO_DEBUG + stackElement->proc = NULL; + stackElement->ptf = NULL; + stackElement->map = NULL; + stackElement->funcCall = NULL; +#endif + return stackElement; +} + +CW_INLINE void StackElement_Delete(StackElement *stackElement) { + IRO_ASSERT(117, stackElement != NULL); + IRO_ASSERT(118, stackElement->proc == NULL); + IRO_ASSERT(119, stackElement->ptf == NULL); + IRO_ASSERT(120, stackElement->map == NULL); + IRO_ASSERT(121, stackElement->funcCall == NULL); + IRO_DEBUG_CLEAR(stackElement, sizeof(StackElement)); + IRO_free(stackElement); +} + +CW_INLINE void StackElement_Init(StackElement *stackElement, Object *proc, PartialTransferFunction *ptf, ParamMappingFunction *map, IROLinear *funcCall) { + IRO_ASSERT(131, stackElement != NULL); + IRO_ASSERT(132, proc != NULL); + IRO_ASSERT(133, ptf != NULL); + IRO_ASSERT(134, map != NULL); + IRO_ASSERT(135, funcCall != NULL); + stackElement->proc = proc; + stackElement->ptf = ptf; + stackElement->map = map; + stackElement->funcCall = funcCall; +} + +CW_INLINE void StackElement_Copy(StackElement *dest, StackElement *src) { + IRO_ASSERT(145, dest != NULL); + IRO_ASSERT(146, src != NULL); + StackElement_Init(dest, src->proc, src->ptf, src->map, src->funcCall); +} + +CW_INLINE void StackElement_Term(StackElement *stackElement) { + IRO_ASSERT(156, stackElement != NULL); +#ifdef IRO_DEBUG + stackElement->proc = NULL; + stackElement->ptf = NULL; + stackElement->map = NULL; + stackElement->funcCall = NULL; +#endif +} + +CW_INLINE void *StackElement_sub_48A780(StackElement *stackElement) { + IRO_ASSERT(213, stackElement != NULL); + return stackElement->proc; +} + +CW_INLINE Boolean StackRelated_sub_48A760(void *key1, void *key2) { + IRO_ASSERT(220, key1 != NULL); + IRO_ASSERT(221, key2 != NULL); + return key1 == key2; +} + +CW_INLINE Object *StackElement_proc(StackElement *stackElement) { + IRO_ASSERT(228, stackElement != NULL); + return stackElement->proc; +} + +CW_INLINE PartialTransferFunction *StackElement_ptf(StackElement *stackElement) { + IRO_ASSERT(235, stackElement != NULL); + return stackElement->ptf; +} + +CW_INLINE ParamMappingFunction *StackElement_map(StackElement *stackElement) { + IRO_ASSERT(242, stackElement != NULL); + return stackElement->map; +} + +CW_INLINE IROLinear *StackElement_funcCall(StackElement *stackElement) { + IRO_ASSERT(249, stackElement != NULL); + return stackElement->funcCall; +} + +CW_INLINE Stack *Stack_New(void) { + Stack *stack = IRO_malloc(sizeof(Stack)); + IRO_ASSERT(265, stack != NULL); +#ifdef IRO_DEBUG + stack->top = NULL; + stack->next = NULL; +#endif + return stack; +} + +CW_INLINE void Stack_Delete(Stack *stack) { + IRO_ASSERT(277, stack != NULL); + IRO_ASSERT(278, stack->top == NULL); + IRO_ASSERT(279, stack->next == NULL); + IRO_DEBUG_CLEAR(stack, sizeof(Stack)); + IRO_free(stack); +} + +CW_INLINE void Stack_Init(Stack *stack) { + IRO_ASSERT(289, stack != NULL); + stack->top = NULL; + stack->next = NULL; +} + +CW_INLINE void Stack_Term(Stack **stackPtr) { + StackElement *stackElement; + + IRO_ASSERT(299, stackPtr != NULL); + IRO_ASSERT(300, *stackPtr != NULL); + + while ((*stackPtr)->top) { + stackElement = Stack_sub_48A5B0(stackPtr); + StackElement_Term(stackElement); + StackElement_Delete(stackElement); + } +} + +CW_INLINE void Stack_sub_48A660(Stack **stackPtr, StackElement *stackElement) { + StackElement *newElement; + Stack *newStack; + + IRO_ASSERT(315, stackPtr != NULL); + IRO_ASSERT(316, *stackPtr != NULL); + + newElement = StackElement_New(); + StackElement_Copy(newElement, stackElement); + + newStack = Stack_New(); + newStack->top = newElement; + newStack->next = *stackPtr; + *stackPtr = newStack; +} + +CW_INLINE StackElement *Stack_Top(Stack **stackPtr) { + IRO_ASSERT(331, stackPtr != NULL); + IRO_ASSERT(332, *stackPtr != NULL); + + return (*stackPtr)->top; +} + +CW_INLINE Stack *Stack_Next(Stack **stackPtr) { + IRO_ASSERT(343, stackPtr != NULL); + IRO_ASSERT(344, *stackPtr != NULL); + + return (*stackPtr)->next; +} + +CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr) { + StackElement *stackElement; + + IRO_ASSERT(357, stackPtr != NULL); + IRO_ASSERT(358, *stackPtr != NULL); + + stackElement = (*stackPtr)->top; + if (stackElement) { + Stack *next = (*stackPtr)->next; + (*stackPtr)->top = NULL; + (*stackPtr)->next = NULL; + Stack_Delete(*stackPtr); + *stackPtr = next; + } + + return stackElement; +} + +CW_INLINE StackElement *Stack_sub_48A710(Stack **stackPtr, void *key) { + Stack *stack; + + IRO_ASSERT(379, stackPtr != NULL); + IRO_ASSERT(380, key != NULL); + + for (stack = *stackPtr; stack; stack = stack->next) { + if (stack->top) { + if (StackRelated_sub_48A760(StackElement_sub_48A780(stack->top), key)) + return stack->top; + } + } + + return NULL; +} + +CW_INLINE ObjectSet *ObjectSet_New(void) { + ObjectSet *procList; + + procList = IRO_malloc(sizeof(ObjectSet)); + IRO_ASSERT(439, procList != NULL); +#ifdef IRO_DEBUG + procList->proc = NULL; + procList->otherProcs = NULL; +#endif + return procList; +} + +CW_INLINE void ObjectSet_Delete(ObjectSet *procList) { + IRO_ASSERT(451, procList != NULL); + IRO_ASSERT(452, procList->proc == NULL); + IRO_ASSERT(453, procList->otherProcs == NULL); + IRO_DEBUG_CLEAR(procList, sizeof(ObjectSet)); + IRO_free(procList); +} + +CW_INLINE void ObjectSet_Init(ObjectSet *procList) { + IRO_ASSERT(463, procList != NULL); + procList->proc = NULL; + procList->otherProcs = NULL; +} + +CW_INLINE void ObjectSet_Term(ObjectSet *procList) { + IRO_ASSERT(481, procList != NULL); + ObjectSet_RemoveAll(procList); +#ifdef IRO_DEBUG + procList->proc = NULL; + procList->otherProcs = NULL; +#endif +} + +CW_INLINE void ObjectSet_ForEach(ObjectSet *procList, void (*action)(Object *, void *), void *refcon) { + IRO_ASSERT(528, procList != NULL); + IRO_ASSERT(529, action != NULL); + IRO_ASSERT(530, refcon == NULL || refcon != NULL); + + while (procList && procList->proc) { + action(procList->proc, refcon); + procList = procList->otherProcs; + } +} + +CW_INLINE Object *ObjectSet_sub_485020(ObjectSet *procList, Object *proc) { + IRO_ASSERT(540, procList != NULL); + IRO_ASSERT(541, proc != NULL); + while (procList && procList->proc) { + if (procList->proc == proc) + return procList->proc; + procList = procList->otherProcs; + } + return NULL; +} + +CW_INLINE Object *ObjectSet_FindFirst(ObjectSet *procList) { + IRO_ASSERT(552, procList != NULL); + return procList->proc; +} + +CW_INLINE int ObjectSet_Count(ObjectSet *procList) { + int count; + + IRO_ASSERT(561, procList != NULL); + + count = 0; + while (procList && procList->proc) { + count++; + procList = procList->otherProcs; + } + + return count; +} + +CW_INLINE void ObjectSet_sub_486800(ObjectSet *procList, Object *proc) { + ObjectSet *newProcList; + + IRO_ASSERT(574, procList != NULL); + IRO_ASSERT(575, proc != NULL); + + if (procList->proc) { + newProcList = ObjectSet_New(); + ObjectSet_Init(newProcList); + newProcList->proc = procList->proc; + newProcList->otherProcs = procList->otherProcs; + procList->otherProcs = newProcList; + } + + procList->proc = proc; +} + +CW_INLINE void ObjectSet_sub_4867D0(ObjectSet *procList, Object *proc) { + IRO_ASSERT(592, procList != NULL); + IRO_ASSERT(593, proc != NULL); + + if (!ObjectSet_sub_485020(procList, proc)) + ObjectSet_sub_486800(procList, proc); +} + +CW_INLINE void ObjectSet_Remove(ObjectSet *procList, Object *proc) { + ObjectSet *prev; + ObjectSet *tmp; + + IRO_ASSERT(605, procList != NULL); + IRO_ASSERT(606, proc != NULL); + + prev = NULL; + while (procList && procList->proc) { + if (procList->proc == proc) { + if (!prev) { + if (procList->otherProcs == NULL) { + procList->proc = NULL; + } else { + tmp = procList->otherProcs; + procList->proc = procList->otherProcs->proc; + procList->otherProcs = procList->otherProcs->otherProcs; + tmp->proc = NULL; + tmp->otherProcs = NULL; + ObjectSet_Term(tmp); + ObjectSet_Delete(tmp); + } + } else { + prev->otherProcs = procList->otherProcs; + procList->proc = NULL; + procList->otherProcs = NULL; + ObjectSet_Term(procList); + ObjectSet_Delete(procList); + } + return; + } + prev = procList; + procList = procList->otherProcs; + } +} + +CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList) { + IRO_ASSERT(645, procList != NULL); + + while (procList && procList->proc) + ObjectSet_Remove(procList, procList->proc); +} + +CW_INLINE void ObjectSet_AddSetAction(Object *proc, void *refcon) { + IRO_ASSERT(655, proc != NULL); + IRO_ASSERT(656, refcon != NULL); + + ObjectSet_sub_4867D0(refcon, proc); +} + +CW_INLINE void ObjectSet_SimpleAddSetAction(Object *proc, void *refcon) { + IRO_ASSERT(663, proc != NULL); + IRO_ASSERT(664, refcon != NULL); + + ObjectSet_sub_486800(refcon, proc); +} + +CW_INLINE void ObjectSet_sub_48C590(ObjectSet *dest, ObjectSet *src) { + IRO_ASSERT(671, dest != NULL); + IRO_ASSERT(672, src != NULL); + + if (dest->proc) + ObjectSet_ForEach(src, ObjectSet_AddSetAction, dest); + else + ObjectSet_ForEach(src, ObjectSet_SimpleAddSetAction, dest); +} + +CW_INLINE void ObjectSet_RemoveSetAction(Object *proc, void *refcon) { + IRO_ASSERT(682, proc != NULL); + IRO_ASSERT(683, refcon != NULL); + + ObjectSet_Remove(refcon, proc); +} + +CW_INLINE void ObjectSet_removeiter_sub_48C890(ObjectSet *dest, ObjectSet *src) { + IRO_ASSERT(690, dest != NULL); + IRO_ASSERT(691, src != NULL); + + ObjectSet_ForEach(src, ObjectSet_RemoveSetAction, dest); +} + +CW_INLINE Boolean ObjectSet_sub_484FA0(ObjectSet *os1, ObjectSet *os2) { + ObjectSet *scan; + + IRO_ASSERT(700, os1 != NULL); + IRO_ASSERT(701, os2 != NULL); + + if (os1 == os2) + return 1; + + for (scan = os1; scan && scan->proc; scan = scan->otherProcs) { + if (!ObjectSet_sub_485020(os2, scan->proc)) + return 0; + } + + for (scan = os2; scan && scan->proc; scan = scan->otherProcs) { + if (!ObjectSet_sub_485020(os1, scan->proc)) + return 0; + } + + return 1; +} + +CW_INLINE ExtendedParam *ExtendedParam_New(void) { + ExtendedParam *ep = IRO_malloc(sizeof(ExtendedParam)); + + IRO_ASSERT(755, ep != NULL); +#ifdef IRO_DEBUG + ep->objectSet = NULL; +#endif + return ep; +} + +CW_INLINE void ExtendedParam_Delete(ExtendedParam *ep) { + IRO_ASSERT(762, ep != NULL); + IRO_ASSERT(763, ep->objectSet == NULL); + IRO_DEBUG_CLEAR(ep, sizeof(ExtendedParam)); + IRO_free(ep); +} + +CW_INLINE void ExtendedParam_Init(ExtendedParam *ep, Object *obj) { + IRO_ASSERT(777, ep != NULL); + IRO_ASSERT(778, obj != NULL); + IRO_ASSERT(779, obj->extParam == NULL); + IRO_ASSERT(780, stExtendedParamNum < ((uint32) -1) / 2 - 1); + + ep->objectSet = ObjectSet_New(); + ObjectSet_Init(ep->objectSet); + ObjectSet_sub_4867D0(ep->objectSet, obj); + obj->extParam = ep; + + ep->x4 = stExtendedParamNum++; +} + +CW_INLINE void ExtendedParam_TermAction(Object *obj, void *refcon) { + obj->extParam = NULL; +} + +CW_INLINE void ExtendedParam_Term(ExtendedParam *ep) { + IRO_ASSERT(800, ep != NULL); + + ObjectSet_ForEach(ep->objectSet, ExtendedParam_TermAction, NULL); + ObjectSet_Term(ep->objectSet); + ObjectSet_Delete(ep->objectSet); +#ifdef IRO_DEBUG + ep->objectSet = NULL; +#endif +} + +CW_INLINE Boolean ExtendedParams_Equal(ExtendedParam *ep1, ExtendedParam *ep2) { + IRO_ASSERT(841, ep1 != NULL); + IRO_ASSERT(842, ep2 != NULL); + IRO_ASSERT(843, ep1->objectSet != NULL); + IRO_ASSERT(844, ep2->objectSet != NULL); + + if (ep1 == ep2) + return 1; + + return ep1->x4 == ep2->x4 && ObjectSet_sub_484FA0(ep1->objectSet, ep2->objectSet); +} + +CW_INLINE ExtendedParam *ExtendedParam_FindByObject(Object *obj) { + IRO_ASSERT(856, obj != NULL); + + return obj->extParam; +} + +CW_INLINE void ExtendedParam_sub_4867B0(ExtendedParam *ep, Object *obj) { + IRO_ASSERT(863, ep != NULL); + IRO_ASSERT(864, ep->objectSet != NULL); + IRO_ASSERT(865, obj != NULL); + + ObjectSet_sub_4867D0(ep->objectSet, obj); + obj->extParam = ep; +} + +CW_INLINE void ExtendedParam_RemoveObjectSetAction(Object *object, void *refcon) { + object->extParam = NULL; +} + +CW_INLINE void EP_sub_48C850(ExtendedParam *ep, ObjectSet *objSet) { + IRO_ASSERT(888, ep != NULL); + IRO_ASSERT(889, ep->objectSet != NULL); + IRO_ASSERT(890, objSet != NULL); + + ObjectSet_removeiter_sub_48C890(ep->objectSet, objSet); + ObjectSet_ForEach(objSet, ExtendedParam_RemoveObjectSetAction, NULL); +} + +CW_INLINE ObjectSet *ExtendedParam_objectSet(ExtendedParam *ep) { + IRO_ASSERT(898, ep != NULL); + + return ep->objectSet; +} + +CW_INLINE uint32 ExtendedParam_sub_489110(ExtendedParam *ep) { + IRO_ASSERT(905, ep != NULL); + + return ep->x4; +} + +CW_INLINE ExtendedParamSet *AllocsExtParamSet_sub_4876C0(void) { + ExtendedParamSet *epList = IRO_malloc(sizeof(ExtendedParamSet)); + + IRO_ASSERT(924, epList != NULL); +#ifdef IRO_DEBUG + epList->ep = NULL; + epList->otherEps = NULL; +#endif + return epList; +} + +CW_INLINE void FreesExtParamSet_sub_48CAE0(ExtendedParamSet *epList) { + IRO_ASSERT(936, epList != NULL); + IRO_ASSERT(937, epList->ep == NULL); + IRO_ASSERT(938, epList->otherEps == NULL); + IRO_DEBUG_CLEAR(epList, sizeof(ExtendedParamSet)); + IRO_free(epList); +} + +CW_INLINE void InitsExtParamSet_sub_4876A0(ExtendedParamSet *epList) { + IRO_ASSERT(948, epList != NULL); + epList->ep = NULL; + epList->otherEps = NULL; +} + +CW_INLINE void TermsExtParamSet_sub_48CB00(ExtendedParamSet *epList) { + IRO_ASSERT(966, epList != NULL); + ExtendedParamSet_RemoveAll(epList); +#ifdef IRO_DEBUG + epList->ep = NULL; + epList->otherEps = NULL; +#endif +} + +CW_INLINE void MaybeWalkExtParamSet_sub_48CBE0(ExtendedParamSet *epList, void (*action)(ExtendedParam *, void *), void *refcon) { + IRO_ASSERT(1010, epList != NULL); + IRO_ASSERT(1011, action != NULL); + + while (epList && epList->ep) { + action(epList->ep, refcon); + epList = epList->otherEps; + } +} + +CW_INLINE ExtendedParam *ExtParamSet_sub_4876D0(ExtendedParamSet *epList, ExtendedParam *ep) { + IRO_ASSERT(1022, epList != NULL); + IRO_ASSERT(1023, ep != NULL); + + while (epList && epList->ep) { + if (epList->ep == ep) + return epList->ep; + epList = epList->otherEps; + } + + return NULL; +} + +CW_INLINE void ExtParamSet_sub_487660(ExtendedParamSet *epList, ExtendedParam *ep) { + IRO_ASSERT(1056, epList != NULL); + IRO_ASSERT(1057, ep != NULL); + + if (epList->ep) { + ExtendedParamSet *newSet = AllocsExtParamSet_sub_4876C0(); + InitsExtParamSet_sub_4876A0(newSet); + newSet->ep = epList->ep; + newSet->otherEps = epList->otherEps; + epList->otherEps = newSet; + } + + epList->ep = ep; +} + +CW_INLINE void ExtParamSet_sub_487630(ExtendedParamSet *epList, ExtendedParam *ep) { + IRO_ASSERT(1076, epList != NULL); + IRO_ASSERT(1077, ep != NULL); + + if (!ExtParamSet_sub_4876D0(epList, ep)) + ExtParamSet_sub_487660(epList, ep); +} + +CW_INLINE void ExtendedParamSet_Remove(ExtendedParamSet *epList, ExtendedParam *ep) { + ExtendedParamSet *prev; + ExtendedParamSet *tmp; + + IRO_ASSERT(1089, epList != NULL); + IRO_ASSERT(1090, ep != NULL); + + prev = NULL; + while (epList && epList->ep) { + if (epList->ep == ep) { + if (!prev) { + if (epList->otherEps == NULL) { + epList->ep = NULL; + } else { + tmp = epList->otherEps; + epList->ep = epList->otherEps->ep; + epList->otherEps = epList->otherEps->otherEps; + tmp->ep = NULL; + tmp->otherEps = NULL; + TermsExtParamSet_sub_48CB00(tmp); + FreesExtParamSet_sub_48CAE0(tmp); + } + } else { + prev->otherEps = epList->otherEps; + epList->ep = NULL; + epList->otherEps = NULL; + TermsExtParamSet_sub_48CB00(epList); + FreesExtParamSet_sub_48CAE0(epList); + } + return; + } + prev = epList; + epList = epList->otherEps; + } +} + +CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList) { + IRO_ASSERT(1129, epList != NULL); + + while (epList && epList->ep) + ExtendedParamSet_Remove(epList, epList->ep); +} + +CW_INLINE PAHeapBlock *CreateUniqueHeapAlloc_sub_486420(void) { + PAHeapBlock *hb = IRO_malloc(sizeof(PAHeapBlock)); + + IRO_ASSERT(1225, hb != NULL); +#ifdef IRO_DEBUG + hb->parent = NULL; +#endif + return hb; +} + +CW_INLINE void InitUniqueHeapAlloc_sub_486410(PAHeapBlock *hb, IROLinear *nd) { + IRO_ASSERT(1247, hb != NULL); + + hb->x0 = nd; +} + +CW_INLINE Boolean PAHeapBlocks_Equal(PAHeapBlock *hb1, PAHeapBlock *hb2) { + IRO_ASSERT(1296, hb1 != NULL); + IRO_ASSERT(1297, hb2 != NULL); + + return (hb1 == hb2) || (hb1->x0 == hb2->x0); +} + +CW_INLINE PALocalVar *PALocalVar_New(void) { + PALocalVar *local = IRO_malloc(sizeof(PALocalVar)); + + IRO_ASSERT(1333, local != NULL); +#ifdef IRO_DEBUG + local->parent = NULL; + local->nextSibling = NULL; +#endif + return local; +} + +CW_INLINE void PALocalVar_InitByObject(PALocalVar *local, Object *obj) { + IRO_ASSERT(1357, local != NULL); + IRO_ASSERT(1358, obj != NULL); + + local->x0 = obj; + if (obj->name && obj->name->name) { + local->x4 = IRO_malloc(strlen(obj->name->name) + 1); + strcpy(local->x4, obj->name->name); + } else { + local->x4 = NULL; + } +} + +CW_INLINE void PALocalVar_InitByName(PALocalVar *local, char *name) { + IRO_ASSERT(1372, local != NULL); + IRO_ASSERT(1373, name != NULL); + + local->x0 = NULL; + local->x4 = IRO_malloc(strlen(name) + 1); + strcpy(local->x4, name); +} + +CW_INLINE Boolean PALocalVars_Equal(PALocalVar *local1, PALocalVar *local2) { + IRO_ASSERT(1419, local1 == NULL || local1 != NULL); + IRO_ASSERT(1420, local2 == NULL || local2 != NULL); + + if (local1 == local2) + return 1; + if (!local1 || !local2) + return 0; + + if (!local1->x0 || !local2->x0) { + if (local1->x4) + return local2->x4 && !strcmp(local1->x4, local2->x4); + } + + return local1->x0 == local2->x0; +} + +CW_INLINE void PALocalVar_SetSth_sub_4847C0(PALocalVar *local, Object *obj) { + IRO_ASSERT(1436, local != NULL); + IRO_ASSERT(1437, obj == NULL || obj != NULL); + + local->x0 = obj; +} + +CW_INLINE Object *PALocalVar_Get0_sub_4847E0(PALocalVar *local) { + IRO_ASSERT(1444, local != NULL); + return local->x0; +} + +CW_INLINE char *PALocalVar_Get4_sub_4847D0(PALocalVar *local) { + IRO_ASSERT(1451, local != NULL); + return local->x4; +} + +CW_INLINE PAMemoryBlock *PAMemoryBlock_New(void) { + PAMemoryBlock *mb = IRO_malloc(sizeof(PAMemoryBlock)); + + IRO_ASSERT(1491, mb != NULL); +#ifdef IRO_DEBUG + mb->kind = PAMEMORYBLOCKKIND_INVALID; +#endif + return mb; +} + +CW_INLINE void PAMemoryBlock_Delete(PAMemoryBlock *mb) { + IRO_ASSERT(1502, mb != NULL); + IRO_ASSERT(1503, mb->kind == PAMEMORYBLOCKKIND_INVALID); + IRO_free(mb); +} + +CW_INLINE void PAMemoryBlock_Init(PAMemoryBlock *mb, PAMemoryBlockKind kind, void *thing) { + IRO_ASSERT(1513, mb != NULL); + IRO_ASSERT(1514, thing == NULL || thing != NULL); + + mb->kind = kind; + switch (mb->kind) { + case PAMEMORYBLOCKKIND_EXTENDEDPARAM: + mb->u.ep = (ExtendedParam *) thing; + break; + case PAMEMORYBLOCKKIND_LOCALVAR: + mb->u.localvar = (PALocalVar *) thing; + break; + case PAMEMORYBLOCKKIND_HEAPBLOCK: + mb->u.heapblock = (PAHeapBlock *) thing; + break; + case PAMEMORYBLOCKKIND_INT: + mb->u.intval = *((CInt64 *) thing); + break; + case PAMEMORYBLOCKKIND_6: + mb->u.x6 = (void *) thing; + break; + default: + CError_FATAL(1535); + } +} + +CW_INLINE void PAMemoryBlock_Term(PAMemoryBlock *mb) { + IRO_ASSERT(1552, mb != NULL); + +#ifdef IRO_DEBUG + mb->kind = PAMEMORYBLOCKKIND_INVALID; +#endif +} + +CW_INLINE Boolean MemoryBlocks_Equal(PAMemoryBlock *mb1, PAMemoryBlock *mb2) { + IRO_ASSERT(1657, mb1 == NULL || mb1 != NULL); + IRO_ASSERT(1658, mb2 == NULL || mb2 != NULL); + + if (mb1 == mb2) + return 1; + + if (!mb1 || !mb2 || mb1->kind != mb2->kind) + return 0; + + switch (mb1->kind) { + case PAMEMORYBLOCKKIND_EXTENDEDPARAM: + return ExtendedParams_Equal(mb1->u.ep, mb2->u.ep); + case PAMEMORYBLOCKKIND_LOCALVAR: + return PALocalVars_Equal(mb1->u.localvar, mb2->u.localvar); + case PAMEMORYBLOCKKIND_HEAPBLOCK: + return PAHeapBlocks_Equal(mb1->u.heapblock, mb2->u.heapblock); + case PAMEMORYBLOCKKIND_INT: + return CInt64_Equal(mb1->u.intval, mb2->u.intval); + case PAMEMORYBLOCKKIND_6: + return mb1->u.x6 == mb2->u.x6; + default: + CError_FATAL(1684); + return 0; + } +} + +CW_INLINE PAMemoryBlockKind PAMemoryBlock_kind(PAMemoryBlock *mb) { + IRO_ASSERT(1692, mb != NULL); + + return mb->kind; +} + +CW_INLINE void *PAMemoryBlock_thing(PAMemoryBlock *mb) { + IRO_ASSERT(1699, mb != NULL); + + switch (mb->kind) { + case PAMEMORYBLOCKKIND_EXTENDEDPARAM: + return mb->u.ep; + case PAMEMORYBLOCKKIND_LOCALVAR: + return mb->u.localvar; + case PAMEMORYBLOCKKIND_HEAPBLOCK: + return mb->u.heapblock; + case PAMEMORYBLOCKKIND_INT: + return &mb->u.intval; + case PAMEMORYBLOCKKIND_6: + return mb->u.x6; + default: + CError_FATAL(1719); + return NULL; + } +} + +CW_INLINE LocationSet *LocationSet_New(void) { + LocationSet *ls = IRO_malloc(sizeof(LocationSet)); + + IRO_ASSERT(1767, ls != NULL); +#ifdef IRO_DEBUG + ls->block = NULL; + ls->rtype = NULL; + ls->u.known.field = cint64_zero; + ls->u.known.stride = 0; +#endif + return ls; +} + +CW_INLINE void LocationSet_Delete(LocationSet *ls) { + IRO_ASSERT(1781, ls != NULL); + IRO_ASSERT(1782, ls != stUnknownLs); + IRO_ASSERT(1783, ls->block == NULL); + IRO_ASSERT(1784, CInt64_IsZero(&ls->u.known.field)); + IRO_ASSERT(1785, ls->u.known.stride == 0); + IRO_ASSERT(1786, ls->rtype == NULL); + IRO_DEBUG_CLEAR(ls, sizeof(LocationSet)); + IRO_free(ls); +} + +CW_INLINE void LocationSet_InitKnown(LocationSet *ls, PAMemoryBlock *block, CInt64 field, UInt32 stride, Type *rtype) { + IRO_ASSERT(1796, ls != NULL); + IRO_ASSERT(1797, ls != stUnknownLs); + IRO_ASSERT(1798, block != NULL); + IRO_ASSERT(1799, rtype == NULL || rtype != NULL); + ls->block = block; + ls->rtype = rtype; + ls->u.known.field = field; + ls->u.known.stride = stride; +} + +CW_INLINE void LocationSet_InitUnknown(LocationSet *ls, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) { + IRO_ASSERT(1809, ls != NULL); + IRO_ASSERT(1810, ls != stUnknownLs); + IRO_ASSERT(1811, rtype == NULL || rtype != NULL); + IRO_ASSERT(1812, restriction == NULL || restriction != NULL); + IRO_ASSERT(1813, bitfieldOf == NULL || bitfieldOf != NULL); + + LocationSet_Copy(ls, stUnknownLs); + ls->rtype = rtype; + ls->u.unknown.restriction = restriction; + if (bitfieldOf) { + ls->u.unknown.bitfieldOf = LocationSet_New(); + LocationSet_Copy(ls->u.unknown.bitfieldOf, bitfieldOf); + } else { + ls->u.unknown.bitfieldOf = NULL; + } +} + +CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src) { + IRO_ASSERT(1829, src != NULL); + IRO_ASSERT(1830, dest != NULL); + + dest->block = src->block; + dest->rtype = src->rtype; + + if (!LocationSet_IsUnknown(src)) { + dest->u.known.field = src->u.known.field; + dest->u.known.stride = src->u.known.stride; + } else { + dest->u.unknown.restriction = src->u.unknown.restriction; + if (src->u.unknown.bitfieldOf != NULL) { + dest->u.unknown.bitfieldOf = LocationSet_New(); + LocationSet_Copy(dest->u.unknown.bitfieldOf, src->u.unknown.bitfieldOf); + } else { + dest->u.unknown.bitfieldOf = NULL; + } + } +} + +CW_INLINE void LocationSet_Term(LocationSet *ls) { + IRO_ASSERT(1857, ls != NULL); + IRO_ASSERT(1858, ls != stUnknownLs); + +#ifdef IRO_DEBUG + if (LocationSet_IsUnknown(ls) && ls->u.unknown.bitfieldOf) { + LocationSet_Term(ls->u.unknown.bitfieldOf); + LocationSet_Delete(ls->u.unknown.bitfieldOf); + } + ls->block = NULL; + ls->rtype = NULL; + ls->u.known.field = cint64_zero; + ls->u.known.stride = 0; +#endif +} + +CW_INLINE Boolean LocationSets_Overlap(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) { + Boolean isUnknown1, isUnknown2; + PAMemoryBlock *restriction1, *restriction2; + + IRO_ASSERT(1974, ls1 != NULL); + IRO_ASSERT(1975, rtype1 == NULL || rtype1 != NULL); + IRO_ASSERT(1976, ls2 != NULL); + IRO_ASSERT(1977, rtype2 == NULL || rtype2 != NULL); + + if (ls1 == ls2) + return 1; + + isUnknown1 = LocationSet_IsUnknown(ls1); + if (isUnknown1) + restriction1 = ls1->u.unknown.restriction; + else + restriction1 = NULL; + + isUnknown2 = LocationSet_IsUnknown(ls2); + if (isUnknown2) + restriction2 = ls2->u.unknown.restriction; + else + restriction2 = NULL; + + if ( + (isUnknown1 && !restriction1) || + (isUnknown2 && !restriction2) || + (isUnknown1 && isUnknown2 && MemoryBlocks_Equal(restriction1, restriction2)) + ) + return 1; + + if (isUnknown1 || isUnknown2) + return 0; + + if (MemoryBlocks_Equal(ls1->block, ls2->block)) { + UInt32 size1; + UInt32 size2; + UInt32 i; + CInt64 work; + CInt64 longgcd; + + if (rtype1) + size1 = rtype1->size; + else + size1 = -1; + + if (rtype2) + size2 = rtype2->size; + else + size2 = -1; + + if (ls1->u.known.stride == ls2->u.known.stride) { + CInt64 longsize1; + CInt64 longsize2; + CInt64_SetULong(&longsize1, size1); + CInt64_SetULong(&longsize2, size2); + + return CInt64_Equal(ls1->u.known.field, ls2->u.known.field) || + (CInt64_Less(ls1->u.known.field, ls2->u.known.field) && CInt64_Greater(CInt64_Add(ls1->u.known.field, longsize1), ls2->u.known.field)) || + (CInt64_Less(ls2->u.known.field, ls1->u.known.field) && CInt64_Greater(CInt64_Add(ls2->u.known.field, longsize2), ls1->u.known.field)); + } else { + work = CInt64_Sub(ls1->u.known.field, ls2->u.known.field); + if (CInt64_IsNegative(&work)) + work = CInt64_Neg(work); + + CInt64_SetULong(&longgcd, gcd(ls1->u.known.stride, ls2->u.known.stride)); + if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero)) + return 1; + + if (size1 == -1) + return 1; + + for (i = 1; i < size1; i++) { + CInt64_SetLong(&work, i); + work = CInt64_Add(work, ls1->u.known.field); + work = CInt64_Sub(work, ls2->u.known.field); + if (CInt64_IsNegative(&work)) + work = CInt64_Neg(work); + if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero)) + return 1; + } + + if (size2 == -1) + return 1; + + for (i = 1; i < size2; i++) { + CInt64_SetLong(&work, i); + work = CInt64_Add(work, ls2->u.known.field); + work = CInt64_Sub(work, ls1->u.known.field); + if (CInt64_IsNegative(&work)) + work = CInt64_Neg(work); + if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero)) + return 1; + } + + return 0; + } + } + + return 0; +} + +CW_INLINE Boolean LocationSets_Equal(LocationSet *ls1, LocationSet *ls2) { + IRO_ASSERT(2080, ls1 != NULL); + IRO_ASSERT(2081, ls2 != NULL); + + return + (ls1 == ls2) || + ( + (LocationSet_IsUnknown(ls1) && LocationSet_IsUnknown(ls2)) && + (MemoryBlocks_Equal(ls1->u.unknown.restriction, ls2->u.unknown.restriction)) && + ((ls1->u.unknown.bitfieldOf == ls2->u.unknown.bitfieldOf) || + (ls1->u.unknown.bitfieldOf && ls2->u.unknown.bitfieldOf && LocationSets_Equal(ls1->u.unknown.bitfieldOf, ls2->u.unknown.bitfieldOf))) && + ((ls1->rtype == ls2->rtype) || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) + ) || + ( + (!LocationSet_IsUnknown(ls1) && !LocationSet_IsUnknown(ls2)) && + (ls1->u.known.stride == ls2->u.known.stride) && + ((ls1->rtype == ls2->rtype) || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) && + CInt64_Equal(ls1->u.known.field, ls2->u.known.field) && + MemoryBlocks_Equal(ls1->block, ls2->block) + ); +} + +CW_INLINE Boolean LocationSets_LookupCompatible(LocationSet *ls1, LocationSet *ls2) { + IRO_ASSERT(2119, ls1 != NULL); + IRO_ASSERT(2120, ls2 != NULL); + + if ( + (ls1 == ls2) || + ( + LocationSet_IsUnknown(ls1) && + LocationSet_IsUnknown(ls2) && + MemoryBlocks_Equal(ls1->u.unknown.restriction, ls2->u.unknown.restriction) && + (ls1->rtype == ls2->rtype || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) + )) + return 1; + + if ( + (!LocationSet_IsUnknown(ls1) && !LocationSet_IsUnknown(ls2)) && + (ls1->rtype == ls2->rtype || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) && + MemoryBlocks_Equal(ls1->block, ls2->block) + ) { + CInt64 work; + CInt64 longgcd; + + if (ls1->u.known.stride == ls2->u.known.stride) + return CInt64_Equal(ls1->u.known.field, ls2->u.known.field); + + work = CInt64_Sub(ls1->u.known.field, ls2->u.known.field); + if (CInt64_IsNegative(&work)) + work = CInt64_Neg(work); + + CInt64_SetULong(&longgcd, gcd(ls1->u.known.stride, ls2->u.known.stride)); + return CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero); + } + + return 0; +} + +CW_INLINE Boolean LocationSet_Contains(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) { + Boolean unknown1; + Boolean unknown2; + PAMemoryBlock *restriction2; + PAMemoryBlock *restriction1; + CInt64 longsize1; + CInt64 longsize2; + + IRO_ASSERT(2168, ls1 != NULL); + IRO_ASSERT(2169, ls2 != NULL); + IRO_ASSERT(2170, rtype1 != NULL); + IRO_ASSERT(2171, rtype2 != NULL); + + if (ls1 == ls2) + return 1; + + unknown1 = LocationSet_IsUnknown(ls1); + if (unknown1) + restriction1 = ls1->u.unknown.restriction; + else + restriction1 = NULL; + + unknown2 = LocationSet_IsUnknown(ls2); + if (unknown2) + restriction2 = ls2->u.unknown.restriction; + else + restriction2 = NULL; + + if (unknown1) + return !restriction1 || (unknown2 && MemoryBlocks_Equal(restriction2, restriction1)); + + CInt64_SetULong(&longsize1, rtype1->size); + CInt64_SetULong(&longsize2, rtype2->size); + + return + !LocationSet_IsUnknown(ls2) && + (ls1->u.known.stride == 0) && + (ls2->u.known.stride == 0) && + rtype1->size >= rtype2->size && + CInt64_LessEqual(ls1->u.known.field, ls2->u.known.field) && + CInt64_GreaterEqual(CInt64_Add(ls1->u.known.field, longsize1), CInt64_Add(ls2->u.known.field, longsize2)) && + MemoryBlocks_Equal(ls1->block, ls2->block); +} + +CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls) { + IRO_ASSERT(2233, ls != NULL); + + return (ls == stUnknownLs) || (ls->block == stUnknownMb); +} + +CW_INLINE Boolean LocationSet_sub_48AF30(LocationSet *ls) { + return + !LocationSet_IsUnknown(ls) && + (ls->u.known.stride == 0) && + CInt64_IsZero(&ls->u.known.field) && + PAMemoryBlock_kind(ls->block) == PAMEMORYBLOCKKIND_LOCALVAR && + !PAMemoryBlock_thing(ls->block); +} + +CW_INLINE void LocationSet_SetRtype(LocationSet *ls, Type *rtype) { + IRO_ASSERT(2263, ls != NULL); + IRO_ASSERT(2264, ls != stUnknownLs); + IRO_ASSERT(2265, rtype != NULL); + + ls->rtype = rtype; +} + +CW_INLINE void SetsLocationSetField_sub_4851B0(LocationSet *ls, CInt64 field) { + IRO_ASSERT(2272, ls != NULL); + IRO_ASSERT(2273, !LocationSet_IsUnknown(ls)); + + ls->u.known.field = field; +} + +CW_INLINE void SetsLocationSetStride_sub_4852D0(LocationSet *ls, SInt32 stride) { + IRO_ASSERT(2280, ls != NULL); + IRO_ASSERT(2281, !LocationSet_IsUnknown(ls)); + + ls->u.known.stride = stride; +} + +CW_INLINE PAMemoryBlock *LocationSet_block(LocationSet *ls) { + IRO_ASSERT(2298, ls != NULL); + + return ls->block; +} + +CW_INLINE Type *LocationSet_rtype(LocationSet *ls) { + IRO_ASSERT(2306, ls != NULL); + IRO_ASSERT(2307, ls != stUnknownLs); + + return ls->rtype; +} + +CW_INLINE CInt64 LocationSet_field(LocationSet *ls) { + IRO_ASSERT(2314, ls != NULL); + IRO_ASSERT(2315, !LocationSet_IsUnknown(ls)); + + return ls->u.known.field; +} + +CW_INLINE UInt32 LocationSet_stride(LocationSet *ls) { + IRO_ASSERT(2322, ls != NULL); + IRO_ASSERT(2323, !LocationSet_IsUnknown(ls)); + + return ls->u.known.stride; +} + +CW_INLINE PAMemoryBlock *LocationSet_restriction(LocationSet *ls) { + IRO_ASSERT(2330, ls != NULL); + IRO_ASSERT(2331, LocationSet_IsUnknown(ls)); + + return ls->u.unknown.restriction; +} + +CW_INLINE LocationSet *LocationSet_bitfieldOf(LocationSet *ls) { + IRO_ASSERT(2338, ls != NULL); + IRO_ASSERT(2339, LocationSet_IsUnknown(ls)); + + return ls->u.unknown.bitfieldOf; +} + +CW_INLINE LocationSetSet *LocationSetSet_New(void) { + LocationSetSet *lss = IRO_malloc(sizeof(LocationSetSet)); + + IRO_ASSERT(2356, lss != NULL); +#ifdef IRO_DEBUG + lss->loc = NULL; + lss->otherLocs = NULL; + lss->count = 0; +#endif + return lss; +} + +CW_INLINE void LocationSetSet_Delete(LocationSetSet *lss) { + IRO_ASSERT(2369, lss != NULL); + IRO_ASSERT(2370, lss->loc == NULL); + IRO_ASSERT(2371, lss->otherLocs == NULL); + IRO_ASSERT(2372, lss->count == 0); + IRO_DEBUG_CLEAR(lss, sizeof(LocationSetSet)); + IRO_free(lss); +} + +CW_INLINE void LocationSetSet_Init(LocationSetSet *lss) { + IRO_ASSERT(2382, lss != NULL); + + lss->loc = NULL; + lss->otherLocs = NULL; + lss->count = 0; +} + +CW_INLINE void LocationSetSet_Copy(LocationSetSet *dest, LocationSetSet *src) { + IRO_ASSERT(2391, dest != NULL); + IRO_ASSERT(2392, src != NULL); + + dest->loc = NULL; + dest->otherLocs = NULL; + dest->count = 0; + LocationSetSet_AddSet(dest, src); +} + +CW_INLINE void LocationSetSet_Term(LocationSetSet *lss) { + IRO_ASSERT(2402, lss != NULL); + + LocationSetSet_RemoveAll(lss); + +#ifdef IRO_DEBUG + lss->loc = NULL; + lss->otherLocs = NULL; + lss->count = 0; +#endif +} + +CW_INLINE void LocationSetSet_ForEach(LocationSetSet *lss, void (*action)(LocationSet *, void *), void *refcon) { + IRO_ASSERT(2446, lss != NULL); + IRO_ASSERT(2447, action != NULL); + IRO_ASSERT(2448, refcon == NULL || refcon != NULL); + + while (lss && lss->loc) { + action(lss->loc, refcon); + lss = lss->otherLocs; + } +} + +CW_INLINE LocationSet *LocationSetSet_Find(LocationSetSet *lss, LocationSet *ls) { + IRO_ASSERT(2458, lss != NULL); + IRO_ASSERT(2459, ls != NULL); + + while (lss && lss->loc) { + if (LocationSets_Equal(lss->loc, ls)) + return lss->loc; + lss = lss->otherLocs; + } + + return NULL; +} + +CW_INLINE LocationSet *LocationSetSet_FindUnknown(LocationSetSet *lss) { + IRO_ASSERT(2470, lss != NULL); + + if (!lss->loc) + return stUnknownLs; + + while (lss && lss->loc) { + if (LocationSet_IsUnknown(lss->loc)) + return lss->loc; + lss = lss->otherLocs; + } + + return NULL; +} + +CW_INLINE LocationSet *LocationSetSet_FindFirst(LocationSetSet *lss) { + IRO_ASSERT(2498, lss != NULL); + + return lss->loc; +} + +CW_INLINE int LocationSetSet_Count(LocationSetSet *lss) { + IRO_ASSERT(2505, lss != NULL); + + return lss->count; +} + +CW_INLINE void LocationSetSet_RemoveAllWithMemoryBlock(LocationSetSet *lss, PAMemoryBlock *block) { + LocationSetSet *first; + LocationSetSet *prev; + LocationSetSet *next; + LocationSetSet *tmp; + + IRO_ASSERT(2514, lss != NULL); + IRO_ASSERT(2515, block != NULL); + + first = lss; + prev = NULL; + while (lss && lss->loc) { + next = lss->otherLocs; + if (MemoryBlocks_Equal(block, lss->loc->block)) { + if (lss->loc != stUnknownLs) { + LocationSet_Term(lss->loc); + LocationSet_Delete(lss->loc); + } + if (!prev) { + if (lss->otherLocs == NULL) { + lss->loc = NULL; + prev = lss; + } else { + tmp = lss->otherLocs; + lss->loc = lss->otherLocs->loc; + lss->otherLocs = lss->otherLocs->otherLocs; + tmp->loc = NULL; + tmp->otherLocs = NULL; + LocationSetSet_Term(tmp); + LocationSetSet_Delete(tmp); + prev = NULL; + next = lss; + } + } else { + prev->otherLocs = lss->otherLocs; + lss->loc = NULL; + lss->otherLocs = NULL; + LocationSetSet_Term(lss); + LocationSetSet_Delete(lss); + prev = lss; + } + first->count--; + } + lss = next; + } +} + +CW_INLINE void LocationSetSet_SimpleAdd(LocationSetSet *lss, LocationSet *ls) { + IRO_ASSERT(2572, lss != NULL); + IRO_ASSERT(2573, ls != NULL); + + if (!LocationSet_IsUnknown(ls) && lss->count < 4) { + LocationSet *ls2; + + if (ls == stUnknownLs) { + ls2 = stUnknownLs; + } else { + ls2 = LocationSet_New(); + LocationSet_Copy(ls2, ls); + } + + if (lss->loc) { + LocationSetSet *lss2 = LocationSetSet_New(); + LocationSetSet_Init(lss2); + lss2->loc = lss->loc; + lss2->otherLocs = lss->otherLocs; + lss->otherLocs = lss2; + } + + lss->loc = ls2; + lss->count++; + } else { + LocationSet *ls2; + + LocationSetSet_RemoveAll(lss); + ls2 = LocationSet_New(); + if (LocationSet_IsUnknown(ls)) { + LocationSet_Copy(ls2, ls); + } else { + LocationSet_Copy(ls2, stUnknownLs); + if (ls->rtype) + LocationSet_SetRtype(ls2, ls->rtype); + } + + lss->loc = ls2; + lss->count = 1; + } +} + +CW_INLINE void LocationSetSet_Add(LocationSetSet *lss, LocationSet *ls) { + IRO_ASSERT(2622, lss != NULL); + IRO_ASSERT(2623, ls != NULL); + + if (!lss->loc || (!LocationSet_IsUnknown(lss->loc) && !LocationSetSet_Find(lss, ls))) { + if (!LocationSet_IsUnknown(ls) && ls->u.known.stride) + LocationSetSet_RemoveAllWithMemoryBlock(lss, ls->block); + LocationSetSet_SimpleAdd(lss, ls); + } +} + +CW_INLINE void LocationSetSet_AddUnknown(LocationSetSet *lss, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) { + LocationSet *ls; + + IRO_ASSERT(2643, lss != NULL); + IRO_ASSERT(2644, rtype == NULL || rtype != NULL); + IRO_ASSERT(2645, restriction == NULL || restriction != NULL); + IRO_ASSERT(2646, bitfieldOf == NULL || bitfieldOf != NULL); + + ls = LocationSet_New(); + LocationSet_InitUnknown(ls, rtype, restriction, bitfieldOf); + LocationSetSet_Add(lss, ls); + LocationSet_Term(ls); + LocationSet_Delete(ls); +} + +CW_INLINE void LocationSetSet_Remove(LocationSetSet *lss, LocationSet *ls) { + LocationSetSet *prev; + LocationSetSet *first; + LocationSetSet *tmp; + + IRO_ASSERT(2659, lss != NULL); + IRO_ASSERT(2660, ls != NULL); + + first = lss; + prev = NULL; + while (lss && lss->loc) { + if (LocationSets_Equal(lss->loc, ls)) { + if (lss->loc != stUnknownLs) { + LocationSet_Term(lss->loc); + LocationSet_Delete(lss->loc); + } + if (!prev) { + if (lss->otherLocs == NULL) { + lss->loc = NULL; + } else { + tmp = lss->otherLocs; + lss->loc = lss->otherLocs->loc; + lss->otherLocs = lss->otherLocs->otherLocs; + tmp->loc = NULL; + tmp->otherLocs = NULL; + LocationSetSet_Term(tmp); + LocationSetSet_Delete(tmp); + } + } else { + prev->otherLocs = lss->otherLocs; + lss->loc = NULL; + lss->otherLocs = NULL; + LocationSetSet_Term(lss); + LocationSetSet_Delete(lss); + } + first->count--; + return; + } + + prev = lss; + lss = lss->otherLocs; + } +} + +CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss) { + IRO_ASSERT(2707, lss != NULL); + + while (lss && lss->loc) + LocationSetSet_Remove(lss, lss->loc); +} + +CW_INLINE void LocationSetSet_AddSetAction(LocationSet *ls, void *refcon) { + IRO_ASSERT(2717, ls != NULL); + IRO_ASSERT(2718, refcon != NULL); + + LocationSetSet_Add((LocationSetSet *) refcon, ls); +} + +CW_INLINE void LocationSetSet_SimpleAddSetAction(LocationSet *ls, void *refcon) { + IRO_ASSERT(2725, ls != NULL); + IRO_ASSERT(2726, refcon != NULL); + + LocationSetSet_SimpleAdd((LocationSetSet *) refcon, ls); +} + +CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src) { + IRO_ASSERT(2733, dest != NULL); + IRO_ASSERT(2734, src != NULL); + + if (dest->count) + LocationSetSet_ForEach(src, LocationSetSet_AddSetAction, dest); + else + LocationSetSet_ForEach(src, LocationSetSet_SimpleAddSetAction, dest); +} + +CW_INLINE void LocationSetSet_RemoveSetAction(LocationSet *ls, void *refcon) { + IRO_ASSERT(2744, ls != NULL); + IRO_ASSERT(2745, refcon != NULL); + + LocationSetSet_Remove((LocationSetSet *) refcon, ls); +} + +CW_INLINE void LocationSetSet_sub_488700(LocationSetSet *dest, LocationSetSet *src) { + IRO_ASSERT(2752, dest != NULL); + IRO_ASSERT(2753, src != NULL); + + LocationSetSet_ForEach(src, LocationSetSet_RemoveSetAction, dest); +} + +CW_INLINE Boolean LocationSetSets_Equal(LocationSetSet *lss1, LocationSetSet *lss2) { + IRO_ASSERT(2826, lss1 != NULL); + IRO_ASSERT(2827, lss2 != NULL); + + if (lss1 == lss2) + return 1; + if (LocationSetSet_Count(lss1) != LocationSetSet_Count(lss2)) + return 0; + + while (lss1 && lss1->loc) { + if (!LocationSetSet_Find(lss2, lss1->loc)) + return 0; + lss1 = lss1->otherLocs; + } + + return 1; +} + +CW_INLINE ParamMapping *ParamMapping_New(void) { + ParamMapping *pm = IRO_malloc(sizeof(ParamMapping)); + + IRO_ASSERT(2885, pm != NULL); +#ifdef IRO_DEBUG + pm->actual = NULL; + pm->formal = NULL; + pm->extended = NULL; +#endif + return pm; +} + +CW_INLINE void ParamMapping_Delete(ParamMapping *pm) { + IRO_ASSERT(2898, pm != NULL); + IRO_ASSERT(2899, pm->actual == NULL); + IRO_ASSERT(2900, pm->formal == NULL); + IRO_ASSERT(2901, pm->extended == NULL); + IRO_DEBUG_CLEAR(pm, sizeof(ParamMapping)); + IRO_free(pm); +} + +CW_INLINE void ParamMapping_Init_PROBABLY(ParamMapping *pm, IROLinear *actual, Object *formal, ExtendedParam *extended) { + IRO_ASSERT(2911, pm != NULL); + + pm->actual = actual; + pm->formal = formal; + pm->extended = extended; +} + +CW_INLINE void ParamMapping_Copy(ParamMapping *dest, ParamMapping *src) { + IRO_ASSERT(2920, src != NULL); + IRO_ASSERT(2921, dest != NULL); + + dest->actual = src->actual; + dest->formal = src->formal; + dest->extended = src->extended; +} + +CW_INLINE void ParamMapping_Term(ParamMapping *pm) { + IRO_ASSERT(2933, pm != NULL); + +#ifdef IRO_DEBUG + pm->actual = NULL; + pm->formal = NULL; + pm->extended = NULL; +#endif +} + +CW_INLINE void ParamMapping_SetExtended(ParamMapping *pm, ExtendedParam *ep) { + IRO_ASSERT(2992, pm != NULL); + + pm->extended = ep; +} + +CW_INLINE IROLinear *ParamMapping_actual(ParamMapping *pm) { + IRO_ASSERT(2999, pm != NULL); + + return pm->actual; +} + +CW_INLINE ExtendedParam *ParamMapping_extended(ParamMapping *pm) { + IRO_ASSERT(3011, pm != NULL); + + return pm->extended; +} + +CW_INLINE ParamMappingFunction *ParamMappingFunction_New(void) { + ParamMappingFunction *pmf = IRO_malloc(sizeof(ParamMappingFunction)); + + IRO_ASSERT(3026, pmf != NULL); +#ifdef IRO_DEBUG + pmf->mapping = NULL; + pmf->otherMappings = NULL; +#endif + return pmf; +} + +CW_INLINE void ParamMappingFunction_Delete(ParamMappingFunction *pmf) { + IRO_ASSERT(3039, pmf != NULL); + IRO_ASSERT(3040, pmf->mapping == NULL); + IRO_ASSERT(3041, pmf->otherMappings == NULL); + IRO_DEBUG_CLEAR(pmf, sizeof(ParamMappingFunction)); + IRO_free(pmf); +} + +CW_INLINE void ParamMappingFunction_Init(ParamMappingFunction *pmf) { + IRO_ASSERT(3050, pmf != NULL); + + pmf->mapping = NULL; + pmf->otherMappings = NULL; +} + +CW_INLINE void ParamMappingFunction_Copy(ParamMappingFunction *dest, ParamMappingFunction *src) { + IRO_ASSERT(3058, src != NULL); + IRO_ASSERT(3059, dest != NULL); + + dest->mapping = NULL; + dest->otherMappings = NULL; + ParamMappingFunction_AddAllMaybe_sub_487C50(dest, src); +} + +CW_INLINE void ParamMappingFunction_Term(ParamMappingFunction *pmf) { + IRO_ASSERT(3068, pmf != NULL); + + ParamMappingFunction_RemoveAll(pmf); + +#ifdef IRO_DEBUG + pmf->mapping = NULL; + pmf->otherMappings = NULL; +#endif +} + +CW_INLINE void pmf_sub_487C70(ParamMappingFunction *pmf, void (*action)(ParamMapping *, void *), void *refcon) { + IRO_ASSERT(3111, pmf != NULL); + IRO_ASSERT(3112, action != NULL); + IRO_ASSERT(3113, refcon == NULL || refcon != NULL); + + while (pmf && pmf->mapping) { + action(pmf->mapping, refcon); + pmf = pmf->otherMappings; + } +} + +CW_INLINE ParamMapping *ParamMappingFunction_FindMappingByFormal(ParamMappingFunction *pmf, Object *formal) { + IRO_ASSERT(3123, pmf != NULL); + IRO_ASSERT(3124, formal != NULL); + + while (pmf && pmf->mapping) { + if (pmf->mapping->formal == formal) + return pmf->mapping; + pmf = pmf->otherMappings; + } + + return NULL; +} + +CW_INLINE void Pmf_Add_sub_486610(ParamMappingFunction *pmf, ParamMapping *mapping) { + ParamMapping *existing; + + IRO_ASSERT(3138, pmf != NULL); + IRO_ASSERT(3139, mapping != NULL); + + existing = ParamMappingFunction_FindMappingByFormal(pmf, mapping->formal); + if (!existing) { + existing = ParamMapping_New(); + ParamMapping_Copy(existing, mapping); + if (pmf->mapping) { + ParamMappingFunction *newPMF = ParamMappingFunction_New(); + ParamMappingFunction_Init(newPMF); + newPMF->mapping = pmf->mapping; + newPMF->otherMappings = pmf->otherMappings; + pmf->otherMappings = newPMF; + } + pmf->mapping = existing; + } else { + existing->actual = mapping->actual; + existing->extended = mapping->extended; + } +} + +CW_INLINE void ParamMappingFunction_Remove(ParamMappingFunction *pmf, ParamMapping *mapping) { + ParamMappingFunction *prev; + ParamMappingFunction *tmp; + + IRO_ASSERT(3170, pmf != NULL); + IRO_ASSERT(3171, mapping != NULL); + + prev = NULL; + while (pmf && pmf->mapping) { + if (pmf->mapping->formal == mapping->formal) { + ParamMapping_Term(pmf->mapping); + ParamMapping_Delete(pmf->mapping); + if (!prev) { + if (pmf->otherMappings == NULL) { + pmf->mapping = NULL; + } else { + tmp = pmf->otherMappings; + pmf->mapping = pmf->otherMappings->mapping; + pmf->otherMappings = pmf->otherMappings->otherMappings; + tmp->mapping = NULL; + tmp->otherMappings = NULL; + ParamMappingFunction_Term(tmp); + ParamMappingFunction_Delete(tmp); + } + } else { + prev->otherMappings = pmf->otherMappings; + pmf->mapping = NULL; + pmf->otherMappings = NULL; + ParamMappingFunction_Term(pmf); + ParamMappingFunction_Delete(pmf); + } + return; + } + + prev = pmf; + pmf = pmf->otherMappings; + } +} + +CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf) { + IRO_ASSERT(3213, pmf != NULL); + + while (pmf && pmf->mapping) + ParamMappingFunction_Remove(pmf, pmf->mapping); +} + +CW_INLINE void ParamMappingFunction_AddFunctionAction(ParamMapping *mapping, void *refcon) { + IRO_ASSERT(3223, mapping != NULL); + IRO_ASSERT(3224, refcon != NULL); + + Pmf_Add_sub_486610((ParamMappingFunction *) refcon, mapping); +} + +CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src) { + IRO_ASSERT(3231, dest != NULL); + IRO_ASSERT(3232, src != NULL); + + pmf_sub_487C70(src, ParamMappingFunction_AddFunctionAction, dest); +} + +CW_INLINE PointsToEntry *PointsToEntry_New(void) { + PointsToEntry *pte = IRO_malloc(sizeof(PointsToEntry)); + + IRO_ASSERT(3288, pte != NULL); +#ifdef IRO_DEBUG + pte->loc = NULL; + pte->locs = NULL; +#endif + return pte; +} + +CW_INLINE void PointsToEntry_Delete(PointsToEntry *pte) { + IRO_ASSERT(3300, pte != NULL); + IRO_ASSERT(3301, pte->loc == NULL); + IRO_ASSERT(3302, pte->locs == NULL); + IRO_DEBUG_CLEAR(pte, sizeof(PointsToEntry)); + IRO_free(pte); +} + +CW_INLINE void PointsToEntry_Init(PointsToEntry *pte, LocationSet *loc, LocationSetSet *locs) { + IRO_ASSERT(3312, pte != NULL); + IRO_ASSERT(3313, loc != NULL); + IRO_ASSERT(3314, !LocationSet_IsUnknown(loc)); + IRO_ASSERT(3315, locs != NULL); + + pte->loc = LocationSet_New(); + LocationSet_Copy(pte->loc, loc); + + pte->locs = LocationSetSet_New(); + LocationSetSet_Copy(pte->locs, locs); +} + +CW_INLINE void PointsToEntry_Copy(PointsToEntry *dest, PointsToEntry *src) { + IRO_ASSERT(3325, src != NULL); + IRO_ASSERT(3326, dest != NULL); + + PointsToEntry_Init(dest, src->loc, src->locs); +} + +CW_INLINE void PointsToEntry_Term(PointsToEntry *pte) { + IRO_ASSERT(3333, pte != NULL); + + LocationSet_Term(pte->loc); + LocationSet_Delete(pte->loc); + LocationSetSet_Term(pte->locs); + LocationSetSet_Delete(pte->locs); + +#ifdef IRO_DEBUG + pte->loc = NULL; + pte->locs = NULL; +#endif +} + +CW_INLINE Boolean PointsToEntries_Equal(PointsToEntry *pte1, PointsToEntry *pte2) { + IRO_ASSERT(3381, pte1 != NULL); + IRO_ASSERT(3382, pte2 != NULL); + + if (pte1 == pte2) + return 1; + + return LocationSets_Equal(pte1->loc, pte2->loc) && LocationSetSets_Equal(pte1->locs, pte2->locs); +} + +CW_INLINE LocationSet *PointsToEntry_loc(PointsToEntry *pte) { + IRO_ASSERT(3407, pte != NULL); + + return pte->loc; +} + +CW_INLINE LocationSetSet *PointsToEntry_locs(PointsToEntry *pte) { + IRO_ASSERT(3414, pte != NULL); + + return pte->locs; +} + +CW_INLINE PointsToFunction *PointsToFunction_New(void) { + PointsToFunction *pointsToFunc = IRO_malloc(sizeof(PointsToFunction)); + + IRO_ASSERT(3430, pointsToFunc != NULL); +#ifdef IRO_DEBUG + pointsToFunc->pte = NULL; + pointsToFunc->otherPtes = NULL; +#endif + return pointsToFunc; +} + +CW_INLINE void PointsToFunction_Delete(PointsToFunction *pointsToFunc) { + IRO_ASSERT(3442, pointsToFunc != NULL); + IRO_ASSERT(3443, pointsToFunc->pte == NULL); + IRO_ASSERT(3444, pointsToFunc->otherPtes == NULL); + IRO_DEBUG_CLEAR(pointsToFunc, sizeof(PointsToFunction)); + IRO_free(pointsToFunc); +} + +CW_INLINE void PointsToFunction_Init(PointsToFunction *pointsToFunc) { + IRO_ASSERT(3454, pointsToFunc != NULL); + + pointsToFunc->pte = NULL; + pointsToFunc->otherPtes = NULL; +} + +CW_INLINE void PointsToFunction_Copy(PointsToFunction *dest, PointsToFunction *src) { + IRO_ASSERT(3462, src != NULL); + IRO_ASSERT(3463, dest != NULL); + + dest->pte = NULL; + dest->otherPtes = NULL; + PointsToFunction_AddAllIGuess_sub_487D80(dest, src); +} + +CW_INLINE void PointsToFunction_Term(PointsToFunction *pointsToFunc) { + IRO_ASSERT(3472, pointsToFunc != NULL); + + PointsToFunction_RemoveAll(pointsToFunc); + +#ifdef IRO_DEBUG + pointsToFunc->pte = NULL; + pointsToFunc->otherPtes = NULL; +#endif +} + +CW_INLINE void PointsToFunction_ForEach(PointsToFunction *pointsToFunc, void (*action)(PointsToEntry *, void *), void *refcon) { + IRO_ASSERT(3515, pointsToFunc != NULL); + IRO_ASSERT(3516, action != NULL); + IRO_ASSERT(3517, refcon == NULL || refcon != NULL); + + while (pointsToFunc && pointsToFunc->pte) { + action(pointsToFunc->pte, refcon); + pointsToFunc = pointsToFunc->otherPtes; + } +} + +CW_INLINE PointsToEntry *PointsToFunction_FindByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) { + IRO_ASSERT(3527, pointsToFunc != NULL); + IRO_ASSERT(3528, ls != NULL); + + while (pointsToFunc && pointsToFunc->pte) { + if (LocationSets_Equal(pointsToFunc->pte->loc, ls)) + return pointsToFunc->pte; + pointsToFunc = pointsToFunc->otherPtes; + } + + return NULL; +} + +CW_INLINE PointsToEntry *PointsToFunction_FindFirst(PointsToFunction *pointsToFunc) { + IRO_ASSERT(3539, pointsToFunc != NULL); + + return pointsToFunc->pte; +} + +CW_INLINE PointsToEntry *PointsToFunction_FindByLookupCompatibleLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) { + IRO_ASSERT(3546, pointsToFunc != NULL); + IRO_ASSERT(3547, ls != NULL); + + while (pointsToFunc && pointsToFunc->pte) { + if (ls->u.known.stride) { + if (LocationSets_Equal(pointsToFunc->pte->loc, ls)) + return pointsToFunc->pte; + } else if (LocationSets_LookupCompatible(pointsToFunc->pte->loc, ls)) { + return pointsToFunc->pte; + } + pointsToFunc = pointsToFunc->otherPtes; + } + + return NULL; +} + +CW_INLINE PointsToEntry *PointsToFunction_FindContainingLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls, Type *rtype) { + IRO_ASSERT(3565, pointsToFunc != NULL); + IRO_ASSERT(3566, ls != NULL); + IRO_ASSERT(3567, rtype != NULL); + + while (pointsToFunc && pointsToFunc->pte) { + if (pointsToFunc->pte->locs->loc && !LocationSet_IsUnknown(pointsToFunc->pte->locs->loc)) { + if (!pointsToFunc->pte->locs->otherLocs && LocationSet_Contains(pointsToFunc->pte->loc, pointsToFunc->pte->locs->loc->rtype, ls, rtype)) + return pointsToFunc->pte; + } + pointsToFunc = pointsToFunc->otherPtes; + } + + return NULL; +} + +CW_INLINE void PointsToFunction_RemoveOverlappingLocations(PointsToFunction *pointsToFunc, PointsToEntry *pte) { + Type *rtype1; + Type *rtype2; + LocationSet *ls; + PointsToFunction *prev; + PointsToFunction *next; + PointsToFunction *tmp; + + IRO_ASSERT(3601, pointsToFunc != NULL); + IRO_ASSERT(3602, pte != NULL); + IRO_ASSERT(3603, pte->locs != NULL); + + if (pte->locs->loc && pte->locs->loc != stUnknownLs) + rtype1 = pte->locs->loc->rtype; + else + rtype1 = NULL; + ls = pte->loc; + IRO_ASSERT(3614, ls != NULL); + + prev = NULL; + while (pointsToFunc && pointsToFunc->pte) { + next = pointsToFunc->otherPtes; + if (pointsToFunc->pte->locs->loc && pointsToFunc->pte->locs->loc != stUnknownLs) + rtype2 = pointsToFunc->pte->locs->loc->rtype; + else + rtype2 = NULL; + + if (LocationSets_Overlap(ls, rtype1, pointsToFunc->pte->loc, rtype2)) { + PointsToEntry_Term(pointsToFunc->pte); + PointsToEntry_Delete(pointsToFunc->pte); + if (!prev) { + if (pointsToFunc->otherPtes == NULL) { + pointsToFunc->pte = NULL; + prev = pointsToFunc; + } else { + tmp = pointsToFunc->otherPtes; + pointsToFunc->pte = pointsToFunc->otherPtes->pte; + pointsToFunc->otherPtes = pointsToFunc->otherPtes->otherPtes; + tmp->pte = NULL; + tmp->otherPtes = NULL; + PointsToFunction_Term(tmp); + PointsToFunction_Delete(tmp); + prev = NULL; + next = pointsToFunc; + } + } else { + prev->otherPtes = pointsToFunc->otherPtes; + pointsToFunc->pte = NULL; + pointsToFunc->otherPtes = NULL; + PointsToFunction_Term(pointsToFunc); + PointsToFunction_Delete(pointsToFunc); + prev = pointsToFunc; + } + } + + pointsToFunc = next; + } +} + +CW_INLINE Boolean ShouldAddNewPointsToEntryToFunction(PointsToFunction *pointsToFunc, PointsToEntry *pte) { + Boolean flag; + Boolean isKnown; + SInt32 stride; + PointsToFunction *next; + LocationSet *loc; + LocationSet *loc2; + Type *rtype1; + Type *rtype2; + LocationSetSet *locs2; + LocationSet *tmp; + LocationSet *unknown; + Boolean flag2; + Boolean flag3; + + IRO_ASSERT(3675, pointsToFunc != NULL); + IRO_ASSERT(3676, pte != NULL); + IRO_ASSERT(3677, pte->locs != NULL); + IRO_ASSERT(3678, PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc) == NULL); + IRO_ASSERT(3679, (unknown = LocationSetSet_FindFirst(pte->locs)) != NULL); + IRO_ASSERT(3680, LocationSet_IsUnknown(unknown)); + IRO_ASSERT(3681, LocationSet_bitfieldOf(unknown) == NULL); + IRO_ASSERT(3682, LocationSet_restriction(unknown) == NULL); + + if (pte->locs->loc && pte->locs->loc != stUnknownLs) + rtype1 = pte->locs->loc->rtype; + else + rtype1 = NULL; + + loc = pte->loc; + IRO_ASSERT(3693, loc != NULL); + + isKnown = !LocationSet_IsUnknown(loc); + if (isKnown) + stride = LocationSet_stride(loc); + + flag = 0; + while (pointsToFunc && pointsToFunc->pte) { + next = pointsToFunc->otherPtes; + + locs2 = pointsToFunc->pte->locs; + + if (locs2->loc && locs2->loc != stUnknownLs) + rtype2 = locs2->loc->rtype; + else + rtype2 = NULL; + + loc2 = pointsToFunc->pte->loc; + + flag2 = !(tmp = LocationSetSet_FindFirst(locs2)) || + !LocationSet_IsUnknown(tmp) || + LocationSet_bitfieldOf(tmp) || + LocationSet_restriction(tmp); + + flag3 = LocationSets_Overlap(loc, rtype1, loc2, rtype2); + + if (!flag && flag3) + flag = 1; + + if (flag3 && (flag2 || (isKnown && stride && LocationSet_stride(loc2) == 0))) + return 1; + + pointsToFunc = next; + } + + return !flag; +} + +CW_INLINE Boolean PointsToFunction_SimpleAdd(PointsToFunction *pointsToFunc, PointsToEntry *pte) { + PointsToEntry *newPTE; + + IRO_ASSERT(3741, pointsToFunc != NULL); + IRO_ASSERT(3742, pte != NULL); + + newPTE = PointsToEntry_New(); + PointsToEntry_Copy(newPTE, pte); + if (pointsToFunc->pte) { + PointsToFunction *newPointsToFunc = PointsToFunction_New(); + PointsToFunction_Init(newPointsToFunc); + newPointsToFunc->pte = pointsToFunc->pte; + newPointsToFunc->otherPtes = pointsToFunc->otherPtes; + pointsToFunc->otherPtes = newPointsToFunc; + } + pointsToFunc->pte = newPTE; + return 1; +} + +CW_INLINE Boolean PointsToFunction_Add(PointsToFunction *pointsToFunc, PointsToEntry *pte) { + IRO_ASSERT(3766, pointsToFunc != NULL); + IRO_ASSERT(3767, pte != NULL); + + if (!PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc)) { + LocationSet *ls; + if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) || + LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) { + PointsToFunction_RemoveOverlappingLocations(pointsToFunc, pte); + if (!LocationSet_IsUnknown(pte->loc) || pte->loc->rtype) + PointsToFunction_SimpleAdd(pointsToFunc, pte); + return 1; + } + } + + return 0; +} + +CW_INLINE Boolean PointsToFunction_AddWithoutChecking(PointsToFunction *pointsToFunc, PointsToEntry *pte) { + LocationSet *ls; + + IRO_ASSERT(3793, pointsToFunc != NULL); + IRO_ASSERT(3794, pte != NULL); + + if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) || + LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) { + PointsToFunction_RemoveOverlappingLocations(pointsToFunc, pte); + if (!LocationSet_IsUnknown(pte->loc) || pte->loc->rtype) + PointsToFunction_SimpleAdd(pointsToFunc, pte); + return 1; + } + + return 0; +} + +CW_INLINE void PointsToFunction_RemoveByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) { + PointsToFunction *prev; + PointsToFunction *tmp; + + IRO_ASSERT(3818, pointsToFunc != NULL); + IRO_ASSERT(3819, ls != NULL); + IRO_ASSERT(3820, !LocationSet_IsUnknown(ls)); + + prev = NULL; + while (pointsToFunc && pointsToFunc->pte) { + if (LocationSets_Equal(pointsToFunc->pte->loc, ls)) { + PointsToEntry_Term(pointsToFunc->pte); + PointsToEntry_Delete(pointsToFunc->pte); + if (!prev) { + if (pointsToFunc->otherPtes == NULL) { + pointsToFunc->pte = NULL; + } else { + tmp = pointsToFunc->otherPtes; + pointsToFunc->pte = pointsToFunc->otherPtes->pte; + pointsToFunc->otherPtes = pointsToFunc->otherPtes->otherPtes; + tmp->pte = NULL; + tmp->otherPtes = NULL; + PointsToFunction_Term(tmp); + PointsToFunction_Delete(tmp); + } + } else { + prev->otherPtes = pointsToFunc->otherPtes; + pointsToFunc->pte = NULL; + pointsToFunc->otherPtes = NULL; + PointsToFunction_Term(pointsToFunc); + PointsToFunction_Delete(pointsToFunc); + } + return; + } + + prev = pointsToFunc; + pointsToFunc = pointsToFunc->otherPtes; + } +} + +CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc) { + IRO_ASSERT(3862, pointsToFunc != NULL); + + while (pointsToFunc && pointsToFunc->pte) + PointsToFunction_RemoveByLocationSet(pointsToFunc, pointsToFunc->pte->loc); +} + +CW_INLINE void PointsToFunction_AddFunctionAction(PointsToEntry *pte, void *refcon) { + IRO_ASSERT(3872, pte != NULL); + IRO_ASSERT(3873, refcon != NULL); + + PointsToFunction_Add((PointsToFunction *) refcon, pte); +} + +CW_INLINE void PointsToFunction_SimpleAddFunctionAction(PointsToEntry *pte, void *refcon) { + IRO_ASSERT(3880, pte != NULL); + IRO_ASSERT(3881, refcon != NULL); + + PointsToFunction_SimpleAdd((PointsToFunction *) refcon, pte); +} + +CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src) { + IRO_ASSERT(3888, dest != NULL); + IRO_ASSERT(3889, src != NULL); + + if (dest->pte) + PointsToFunction_ForEach(src, PointsToFunction_AddFunctionAction, dest); + else + PointsToFunction_ForEach(src, PointsToFunction_SimpleAddFunctionAction, dest); +} + +CW_INLINE void PointsToFunction_SortByExtendedParamNum(PointsToFunction *pointsToFunc) { + UInt32 value1; + UInt32 value2; + PointsToFunction *scan; + + while (pointsToFunc && pointsToFunc->pte) { + value1 = 0; + if (pointsToFunc->pte->loc && pointsToFunc->pte->loc->block) { + PAMemoryBlock *block = pointsToFunc->pte->loc->block; + if (block->kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM && block->u.ep) { + value1 = 2 * (block->u.ep->x4) + 1; + } else if (block->kind == PAMEMORYBLOCKKIND_LOCALVAR && block->u.localvar) { + if (block->u.localvar->x0 && block->u.localvar->x0->extParam) + value1 = 2 * block->u.localvar->x0->extParam->x4; + } + } + + for (scan = pointsToFunc->otherPtes; scan && scan->pte; scan = scan->otherPtes) { + value2 = 0; + if (scan->pte->loc && scan->pte->loc->block) { + PAMemoryBlock *block = scan->pte->loc->block; + if (block->kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM && block->u.ep) { + value2 = 2 * (block->u.ep->x4) + 1; + } else if (block->kind == PAMEMORYBLOCKKIND_LOCALVAR && block->u.localvar) { + if (block->u.localvar->x0 && block->u.localvar->x0->extParam) + value2 = 2 * block->u.localvar->x0->extParam->x4; + } + } + + if (value2 < value1) { + LocationSet *saveloc; + LocationSetSet *savelocs; + saveloc = pointsToFunc->pte->loc; + savelocs = pointsToFunc->pte->locs; + pointsToFunc->pte->loc = scan->pte->loc; + pointsToFunc->pte->locs = scan->pte->locs; + scan->pte->loc = saveloc; + scan->pte->locs = savelocs; + } + } + + pointsToFunc = pointsToFunc->otherPtes; + } +} + +CW_INLINE Boolean PointsToFunctions_Equal(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) { + PointsToFunction *scan; + PointsToEntry *pte; + + IRO_ASSERT(3968, pointsToFunc1 != NULL); + IRO_ASSERT(3969, pointsToFunc2 != NULL); + + if (pointsToFunc1 == pointsToFunc2) + return 1; + + for (scan = pointsToFunc1; scan && scan->pte; scan = scan->otherPtes) { + pte = PointsToFunction_FindByLocationSet(pointsToFunc2, scan->pte->loc); + if (!pte || !PointsToEntries_Equal(pte, scan->pte)) + return 0; + } + + for (scan = pointsToFunc2; scan && scan->pte; scan = scan->otherPtes) { + pte = PointsToFunction_FindByLocationSet(pointsToFunc1, scan->pte->loc); + if (!pte || !PointsToEntries_Equal(pte, scan->pte)) + return 0; + } + + return 1; +} + +CW_INLINE Boolean PointsToFunctions_Match(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) { + return 1; +} + +CW_INLINE PartialTransferFunction *PartialTransferFunction_New(void) { + PartialTransferFunction *ptf = IRO_malloc(sizeof(PartialTransferFunction)); + + IRO_ASSERT(4110, ptf != NULL); +#ifdef IRO_DEBUG + ptf->initialPointsToFn = NULL; + ptf->finalPointsToFn = NULL; + ptf->funcModifies = NULL; + ptf->context.nd = NULL; + ptf->context.ptf = NULL; + ptf->returnLocation = NULL; +#endif + return ptf; +} + +CW_INLINE void PartialTransferFunction_Delete(PartialTransferFunction *ptf) { + IRO_ASSERT(4126, ptf != NULL); + IRO_ASSERT(4127, ptf->initialPointsToFn == NULL); + IRO_ASSERT(4128, ptf->finalPointsToFn == NULL); + IRO_ASSERT(4129, ptf->funcModifies == NULL); + IRO_ASSERT(4130, ptf->context.nd == NULL); + IRO_ASSERT(4131, ptf->context.ptf == NULL); + IRO_ASSERT(4132, ptf->returnLocation == NULL); + IRO_DEBUG_CLEAR(ptf, sizeof(PartialTransferFunction)); + IRO_free(ptf); +} + +CW_INLINE void PartialTransferFunction_Init(PartialTransferFunction *ptf, IROLinear *contextNd, PartialTransferFunction *contextPTF) { + IRO_ASSERT(4142, ptf != NULL); + IRO_ASSERT(4143, contextNd != NULL); + IRO_ASSERT(4144, contextPTF != NULL); + + ptf->initialPointsToFn = PointsToFunction_New(); + PointsToFunction_Init(ptf->initialPointsToFn); + ptf->finalPointsToFn = PointsToFunction_New(); + PointsToFunction_Init(ptf->finalPointsToFn); + + ptf->funcModifies = LocationSetSet_New(); + LocationSetSet_Init(ptf->funcModifies); + LocationSetSet_AddUnknown(ptf->funcModifies, NULL, NULL, NULL); + + ptf->returnLocation = NULL; + ptf->x10 = 0; + + ptf->context.nd = contextNd; + ptf->context.ptf = contextPTF; +} + +CW_INLINE void PartialTransferFunction_Copy(PartialTransferFunction *dest, PartialTransferFunction *src) { + IRO_ASSERT(4164, src != NULL); + IRO_ASSERT(4165, dest != NULL); + + dest->initialPointsToFn = PointsToFunction_New(); + PointsToFunction_Copy(dest->initialPointsToFn, src->initialPointsToFn); + dest->finalPointsToFn = PointsToFunction_New(); + PointsToFunction_Copy(dest->finalPointsToFn, src->finalPointsToFn); + + dest->funcModifies = LocationSetSet_New(); + LocationSetSet_Copy(dest->funcModifies, src->funcModifies); + + if (src->returnLocation) { + dest->returnLocation = LocationSet_New(); + LocationSet_Copy(dest->returnLocation, src->returnLocation); + } else { + dest->returnLocation = NULL; + } + + dest->x10 = src->x10; + dest->context = src->context; +} + +CW_INLINE void PartialTransferFunction_Term(PartialTransferFunction *ptf) { + IRO_ASSERT(4190, ptf != NULL); + + PointsToFunction_Term(ptf->initialPointsToFn); + PointsToFunction_Delete(ptf->initialPointsToFn); + PointsToFunction_Term(ptf->finalPointsToFn); + PointsToFunction_Delete(ptf->finalPointsToFn); + LocationSetSet_Term(ptf->funcModifies); + LocationSetSet_Delete(ptf->funcModifies); + + if (ptf->returnLocation) { + PAMemoryBlock_Term(ptf->returnLocation->block); + PAMemoryBlock_Delete(ptf->returnLocation->block); + LocationSet_Term(ptf->returnLocation); + LocationSet_Delete(ptf->returnLocation); + ptf->returnLocation = NULL; + } + +#ifdef IRO_DEBUG + ptf->initialPointsToFn = NULL; + ptf->finalPointsToFn = NULL; + ptf->funcModifies = NULL; + ptf->context.nd = NULL; + ptf->context.ptf = NULL; +#endif +} + +CW_INLINE PointsToFunction *PartialTransferFunction_initialPointsToFn(PartialTransferFunction *ptf) { + IRO_ASSERT(4221, ptf != NULL); + + return ptf->initialPointsToFn; +} + +CW_INLINE PointsToFunction *PartialTransferFunction_finalPointsToFn(PartialTransferFunction *ptf) { + IRO_ASSERT(4227, ptf != NULL); + + return ptf->finalPointsToFn; +} + +CW_INLINE LocationSetSet *PTF_sub_48D750(PartialTransferFunction *ptf) { + IRO_ASSERT(4233, ptf != NULL); + + return ptf->funcModifies; +} + +CW_INLINE LocationSet *PartialTransferFunction_returnLocation(PartialTransferFunction *ptf) { + IRO_ASSERT(4249, ptf != NULL); + + if (!ptf->returnLocation) { + PAMemoryBlock *block; + LocationSet *ls; + + block = PAMemoryBlock_New(); + PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_LOCALVAR, NULL); + ls = LocationSet_New(); + LocationSet_InitKnown(ls, block, cint64_zero, 0, TYPE(&void_ptr)); + ptf->returnLocation = ls; + } + + return ptf->returnLocation; +} + +CW_INLINE IROLinear *PTF_sub_48B980(PartialTransferFunction *ptf) { + IRO_ASSERT(4265, ptf != NULL); + + return ptf->context.nd; +} + +CW_INLINE PartialTransferFunction *PTF_sub_48B970(PartialTransferFunction *ptf) { + IRO_ASSERT(4271, ptf != NULL); + + return ptf->context.ptf; +} + +CW_INLINE void PartialTransferFunction_sub_48A610(PartialTransferFunction *ptf, Boolean value) { + IRO_ASSERT(4298, ptf != NULL); + + ptf->x10 = (value != 0) ? 1 : 0; +} + +CW_INLINE PTFList *PTFList_New(void) { + PTFList *ptfList = IRO_malloc(sizeof(PTFList)); + + IRO_ASSERT(4393, ptfList != NULL); +#ifdef IRO_DEBUG + ptfList->ptf = NULL; + ptfList->otherPTFs = NULL; +#endif + return ptfList; +} + +CW_INLINE void PTFList_Delete(PTFList *ptfList) { + IRO_ASSERT(4405, ptfList != NULL); + IRO_ASSERT(4406, ptfList->ptf == NULL); + IRO_ASSERT(4407, ptfList->otherPTFs == NULL); + IRO_DEBUG_CLEAR(ptfList, sizeof(PTFList)); + IRO_free(ptfList); +} + +CW_INLINE void PTFList_Init(PTFList *ptfList) { + IRO_ASSERT(4417, ptfList != NULL); + + ptfList->ptf = NULL; + ptfList->otherPTFs = NULL; +} + +CW_INLINE void PTFList_Term(PTFList *ptfList) { + IRO_ASSERT(4435, ptfList != NULL); + + PTFList_RemoveAll(ptfList); + +#ifdef IRO_DEBUG + ptfList->ptf = NULL; + ptfList->otherPTFs = NULL; +#endif +} + +CW_INLINE void PTFList_ForEach(PTFList *ptfList, void (*action)(PartialTransferFunction *, void *), void *refcon) { + IRO_ASSERT(4478, ptfList != NULL); + IRO_ASSERT(4479, action != NULL); + IRO_ASSERT(4480, refcon == NULL || refcon != NULL); + + while (ptfList && ptfList->ptf) { + action(ptfList->ptf, refcon); + ptfList = ptfList->otherPTFs; + } +} + +CW_INLINE PartialTransferFunction *PTFList_sub_48A0F0(PTFList *ptfList, PartialTransferFunction *ptf) { + IRO_ASSERT(4490, ptfList != NULL); + IRO_ASSERT(4491, ptf != NULL); + + while (ptfList && ptfList->ptf) { + if (ptfList->ptf == ptf) + return ptfList->ptf; + + ptfList = ptfList->otherPTFs; + } + + return NULL; +} + +CW_INLINE PartialTransferFunction *PTFList_FindFirst(PTFList *ptfList) { + IRO_ASSERT(4502, ptfList != NULL); + + return ptfList->ptf; +} + +CW_INLINE void PTFList_sub_48A080(PTFList *ptfList, PartialTransferFunction *ptf) { + IRO_ASSERT(4511, ptfList != NULL); + IRO_ASSERT(4512, ptf != NULL); + + if (ptfList->ptf) { + PTFList *newList = PTFList_New(); + PTFList_Init(newList); + newList->ptf = ptfList->ptf; + newList->otherPTFs = ptfList->otherPTFs; + ptfList->otherPTFs = newList; + } + + ptfList->ptf = ptf; +} + +CW_INLINE void PTFList_sub_48A050(PTFList *ptfList, PartialTransferFunction *ptf) { + IRO_ASSERT(4529, ptfList != NULL); + IRO_ASSERT(4530, ptf != NULL); + + if (!PTFList_sub_48A0F0(ptfList, ptf)) + PTFList_sub_48A080(ptfList, ptf); +} + +CW_INLINE void PTFList_Remove(PTFList *ptfList, PartialTransferFunction *ptf) { + PTFList *prev; + PTFList *tmp; + + IRO_ASSERT(4542, ptfList != NULL); + IRO_ASSERT(4543, ptf != NULL); + + prev = NULL; + while (ptfList && ptfList->ptf) { + if (ptfList->ptf == ptf) { + if (!prev) { + if (ptfList->otherPTFs == NULL) { + ptfList->ptf = NULL; + } else { + tmp = ptfList->otherPTFs; + ptfList->ptf = ptfList->otherPTFs->ptf; + ptfList->otherPTFs = ptfList->otherPTFs->otherPTFs; + tmp->ptf = NULL; + tmp->otherPTFs = NULL; + PTFList_Term(tmp); + PTFList_Delete(tmp); + } + } else { + prev->otherPTFs = ptfList->otherPTFs; + ptfList->ptf = NULL; + ptfList->otherPTFs = NULL; + PTFList_Term(ptfList); + PTFList_Delete(ptfList); + } + return; + } + + prev = ptfList; + ptfList = ptfList->otherPTFs; + } +} + +CW_INLINE void PTFList_RemoveAll(PTFList *ptfList) { + IRO_ASSERT(4582, ptfList != NULL); + + while (ptfList && ptfList->ptf) + PTFList_Remove(ptfList, ptfList->ptf); +} |