Skip to content

Commit

Permalink
Make guesses in deterministic order
Browse files Browse the repository at this point in the history
  • Loading branch information
sei-eschwartz committed Sep 15, 2021
1 parent f6428d9 commit 1de0f13
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 27 deletions.
58 changes: 31 additions & 27 deletions share/prolog/oorules/guess.pl
Expand Up @@ -68,6 +68,7 @@
% --------------------------------------------------------------------------------------------
guessVirtualFunctionCall(Out) :-
reportFirstSeen('guessVirtualFunctionCall'),

minof((Insn, Constructor, OOffset, VFTable, VOffset),
(likelyVirtualFunctionCall(Insn, Constructor, OOffset, VFTable, VOffset),
not(factNOTConstructor(Constructor)),
Expand Down Expand Up @@ -97,7 +98,8 @@
reportFirstSeen('guessVFTable'),
% See the commentary at possibleVFTable for how this goal constrains our guesses (and
% ordering).
possibleVFTable(VFTable),

osetof2(VFTable, possibleVFTable(VFTable)),
doNotGuessHelper(factVFTable(VFTable),
factNOTVFTable(VFTable)),

Expand All @@ -122,7 +124,8 @@
% --------------------------------------------------------------------------------------------
guessVBTable(Out) :-
reportFirstSeen('guessVBTable'),
validVBTableWrite(_Insn, Method, _Offset, VBTable),

osetof2(VBTable, validVBTableWrite(_Insn, Method, _Offset, VBTable)),
factMethod(Method),
doNotGuessHelper(factVBTable(VBTable),
factNOTVBTable(VBTable)),
Expand Down Expand Up @@ -190,14 +193,14 @@

guessVFTableEntry(Out) :-
reportFirstSeen('guessVFTableEntry'),
guessVFTableEntry1(VFTable, Offset, Entry),
osetof2((VFTable, Offset, Entry), guessVFTableEntry1(VFTable, Offset, Entry)),

tryOrNot(tryVFTableEntry(VFTable, Offset, Entry, guessVFTableEntry1),
tryNOTVFTableEntry(VFTable, Offset, Entry, guessVFTableEntry1),
Out).

guessVFTableEntry(Out) :-
guessVFTableEntry2(VFTable, Offset, Entry),
osetof2((VFTable, Offset, Entry), guessVFTableEntry2(VFTable, Offset, Entry)),

tryOrNot(tryVFTableEntry(VFTable, Offset, Entry, guessVFTableEntry2),
tryNOTVFTableEntry(VFTable, Offset, Entry, guessVFTableEntry2),
Expand Down Expand Up @@ -232,7 +235,7 @@
factEmbeddedObject(DerivedClass, BaseClass, Offset)).

guessDerivedClass(Out) :-
guessDerivedClass(DerivedClass, BaseClass, Offset),
osetof2((DerivedClass, BaseClass, Offset), guessDerivedClass(DerivedClass, BaseClass, Offset)),

tryOrNot(tryDerivedClass(DerivedClass, BaseClass, Offset, guessDerivedClass),
tryEmbeddedObject(DerivedClass, BaseClass, Offset, guessDerivedClass),
Expand Down Expand Up @@ -292,7 +295,7 @@

guessMethod(Out) :-
reportFirstSeen('guessMethod'),
guessMethodA(Method),
osetof2(Method, guessMethodA(Method)),

tryOrNot(tryMethod(Method, guessMethodA),
tryNOTMethod(Method, guessMethodA),
Expand All @@ -313,7 +316,7 @@
% Guess that calls passed offsets into existing objects are methods. This rule is not
% literally true, but objects are commonly in other objects.
guessMethod(Out) :-
guessMethodB(Method),
osetof2(Method, guessMethodB(Method)),

tryOrNot(tryMethod(Method, guessMethodB),
tryNOTMethod(Method, guessMethodB),
Expand All @@ -335,7 +338,7 @@
factMethod(Caller).

guessMethod(Out) :-
guessMethodC(Method),
osetof2(Method, guessMethodC(Method)),

tryOrNot(tryMethod(Method, guessMethodC),
tryNOTMethod(Method, guessMethodC),
Expand All @@ -359,7 +362,7 @@
iso_dif(Caller1, Caller3).

guessMethod(Out) :-
guessMethodD(Method),
osetof2(Method, guessMethodD(Method)),
tryOrNot(tryMethod(Method, guessMethodD),
tryNOTMethod(Method, guessMethodD),
Out).
Expand All @@ -381,7 +384,7 @@


guessMethod(Out) :-
guessMethodE(Method),
osetof2(Method, guessMethodE(Method)),

tryOrNot(tryMethod(Method, guessMethodE),
tryNOTMethod(Method, guessMethodE),
Expand All @@ -399,7 +402,7 @@
(possibleConstructor(Method); possibleDestructor(Method)).

guessMethod(Out) :-
guessMethodF(Method),
osetof2(Method, guessMethodF(Method)),

tryOrNot(tryMethod(Method, guessMethodF),
tryNOTMethod(Method, guessMethodF),
Expand All @@ -415,7 +418,7 @@
(possibleConstructor(Method); possibleDestructor(Method)).

guessMethod(Out) :-
guessMethodG(Method),
osetof2(Method, guessMethodG(Method)),

tryOrNot(tryMethod(Method, guessMethodG),
tryNOTMethod(Method, guessMethodG),
Expand Down Expand Up @@ -473,7 +476,7 @@

guessConstructor(Out) :-
reportFirstSeen('guessConstructor'),
guessConstructor1(Method),
osetof2(Method, guessConstructor1(Method)),

tryOrNot(tryConstructor(Method, guessConstructor1),
tryNOTConstructor(Method, guessConstructor1),
Expand All @@ -492,7 +495,7 @@
factNOTConstructor(Method)).

guessConstructor(Out) :-
guessConstructor2(Method),
osetof2(Method, guessConstructor2(Method)),

tryOrNot(tryConstructor(Method, guessConstructor2),
tryNOTConstructor(Method, guessConstructor2),
Expand All @@ -511,7 +514,7 @@
factNOTConstructor(Method)).

guessConstructor(Out) :-
guessConstructor3(Method),
osetof2(Method, guessConstructor3(Method)),

tryOrNot(tryConstructor(Method, guessConstructor3),
tryNOTConstructor(Method, guessConstructor3),
Expand All @@ -530,7 +533,7 @@

guessUnlikelyConstructor(Out) :-
reportFirstSeen('guessUnlikelyConstructor'),
guessConstructor4(Method),
osetof2(Method, guessConstructor4(Method)),

tryOrNot(tryConstructor(Method, guessConstructor4),
tryNOTConstructor(Method, guessConstructor4),
Expand Down Expand Up @@ -569,7 +572,7 @@

guessClassHasNoBase(Out) :-
reportFirstSeen('guessClassHasNoBase'),
guessClassHasNoBaseB(Class),
osetof2(Class, guessClassHasNoBaseB(Class)),

tryOrNot(tryClassHasNoBase(Class, guessClassHasNoBaseB),
tryClassHasUnknownBase(Class, guessClassHasNoBaseB),
Expand All @@ -586,7 +589,7 @@
factClassHasUnknownBase(Class)).

guessClassHasNoBase(Out) :-
guessClassHasNoBaseC(Class),
osetof2(Class, guessClassHasNoBaseC(Class)),

tryOrNot(tryClassHasNoBase(Class, guessClassHasNoBaseC),
tryClassHasUnknownBase(Class, guessClassHasNoBaseC),
Expand Down Expand Up @@ -620,7 +623,7 @@

guessCommitClassHasNoBase(Out) :-
reportFirstSeen('guessCommitClassHasNoBase'),
guessClassHasNoBaseSpecial(Class),
osetof2(Class, guessClassHasNoBaseSpecial(Class)),

tryOrNot(tryClassHasNoBase(Class, guessCommitClassHasNoBase),
tryClassHasUnknownBase(Class, guessCommitClassHasNoBase),
Expand Down Expand Up @@ -751,7 +754,7 @@
true.

guessNOTMergeClasses(Out) :-
guessNOTMergeClassesSymmetric(Class1, Class2),
osetof2((Class1, Class2), guessNOTMergeClassesSymmetric(Class1, Class2)),

tryOrNot(tryNOTMergeClasses(Class1, Class2, guessNOTMergeClasses),
tryMergeClasses(Class1, Class2, guessNOTMergeClasses),
Expand Down Expand Up @@ -1224,7 +1227,7 @@

% Prioritize methods called by deleteing destructors.
guessFinalRealDestructor(Out) :-
minimalRealDestructor(Method),
osetof2(Method, minimalRealDestructor(Method)),
callTarget(_Insn, OtherDestructor, Method),
factDeletingDestructor(OtherDestructor),

Expand All @@ -1234,7 +1237,7 @@

% Prioritize methods that call other real destructors.
guessFinalRealDestructor(Out) :-
minimalRealDestructor(Method),
osetof2(Method, minimalRealDestructor(Method)),
callTarget(_Insn, Method, OtherDestructor),
factRealDestructor(OtherDestructor),

Expand All @@ -1245,7 +1248,7 @@
% Prioritize methods that do not call delete to avoid confusion with deleting destructors.
% This eliminates a couple of false positives in the fast test suite.
guessFinalRealDestructor(Out) :-
minimalRealDestructor(Method),
osetof2(Method, minimalRealDestructor(Method)),
not(insnCallsDelete(_Insn, Method, _SV)),

tryOrNot(tryRealDestructor(Method, guessFinalRealDestructor3),
Expand All @@ -1254,7 +1257,7 @@

% Guess if it meets the minimal criteria.
guessFinalRealDestructor(Out) :-
minimalRealDestructor(Method),
osetof2(Method, minimalRealDestructor(Method)),

tryOrNot(tryRealDestructor(Method, guessFinalRealDestructor4),
tryNOTRealDestructor(Method, guessFinalRealDestructor4),
Expand Down Expand Up @@ -1290,7 +1293,7 @@

guessDeletingDestructor(Out) :-
reportFirstSeen('guessDeletingDestructor'),
likelyAVirtualDestructor(Method),
minof(Method, likelyAVirtualDestructor(Method)),
doNotGuessHelper(factDeletingDestructor(Method),
factNOTDeletingDestructor(Method)),
!,
Expand All @@ -1312,7 +1315,8 @@

guessFinalDeletingDestructor(Out) :-
reportFirstSeen('guessFinalDeletingDestructor'),
possibleDestructor(Method),

osetof2(Method, possibleDestructor(Method)),
doNotGuessHelper(factDeletingDestructor(Method),
factNOTDeletingDestructor(Method)),

Expand All @@ -1334,7 +1338,7 @@
%
guessFinalDeletingDestructor(Out) :-
% Establish that the candidate meets minimal requirements.
possibleDestructor(Method),
osetof2(Method, possibleDestructor(Method)),
doNotGuessHelper(factDeletingDestructor(Method),
factNOTDeletingDestructor(Method)),

Expand Down
6 changes: 6 additions & 0 deletions share/prolog/oorules/util.pl
Expand Up @@ -36,13 +36,19 @@

:- meta_predicate
osetof(?, ^, -),
osetof2(?, ^),
minof(?, ^).

osetof(A, B, C) :-
bagof(A, B, Cp),
list_to_set(Cp, Cp2),
(deterministicEnabled -> sort(Cp2, C); C = Cp2).

% This function returns answers in a deterministic order
osetof2(A, B) :-
osetof(A, B, Csort),
member(A, Csort).

minof(A, B) :-
deterministicEnabled
->
Expand Down

0 comments on commit 1de0f13

Please sign in to comment.