X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FProgrammersManual.html;h=fad5edf1801bf2ab8cbfc4369345dc145d6219e8;hb=3dda08ad5d52a510ba2239cc4b73757db303a095;hp=7bec1b964dc85a9ca95caedfe790947e2f8d4e6d;hpb=2e438ca03b69ce199f9d567fc5e4ca028d1018c4;p=oota-llvm.git diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 7bec1b964dc..fad5edf1801 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -138,7 +138,8 @@ with another Value
The cast<> operator is a "checked cast" operation. It - converts a pointer or reference from a base class to a derived cast, causing + converts a pointer or reference from a base class to a derived class, causing an assertion failure if it is not really an instance of the right type. This should be used in cases where you have some information that makes you believe that something is of the right type. An example of the isa<> @@ -1484,8 +1486,8 @@ small example that shows how to dump all instructions in a function to the stand #include "llvm/Support/InstIterator.h" // F is a pointer to a Function instance -for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) - llvm::cerr << *i << "\n"; +for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) + llvm::cerr << *I << "\n"; @@ -1497,7 +1499,10 @@ F, all you would need to do is something like:
std::set<Instruction*> worklist; -worklist.insert(inst_begin(F), inst_end(F)); +// or better yet, SmallPtrSet<Instruction*, 64> worklist; + +for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) + worklist.insert(&*I);
Instruction *I = .. ; -BasicBlock *BB = I->getParent(); - -BB->getInstList().erase(I); +I->eraseFromParent();
The +User class provides a base for expressing the ownership of User +towards other +Values. The +Use helper class is employed to do the bookkeeping and to facilitate O(1) +addition and removal.
+ + + + ++A subclass of User can choose between incorporating its Use objects +or refer to them out-of-line by means of a pointer. A mixed variant +(some Uses inline others hung off) is impractical and breaks the invariant +that the Use objects belonging to the same User form a contiguous array. +
++We have 2 different layouts in the User (sub)classes: +
Layout a) +The Use object(s) are inside (resp. at fixed offset) of the User +object and there are a fixed number of them.
+ +Layout b) +The Use object(s) are referenced by a pointer to an +array from the User object and there may be a variable +number of them.
++As of v2.4 each layout still possesses a direct pointer to the +start of the array of Uses. Though not mandatory for layout a), +we stick to this redundancy for the sake of simplicity. +The User object also stores the number of Use objects it +has. (Theoretically this information can also be calculated +given the scheme presented below.)
++Special forms of allocation operators (operator new) +enforce the following memory layouts:
+ +Layout a) is modelled by prepending the User object by the Use[] array.
+ ++...---.---.---.---.-------... + | P | P | P | P | User +'''---'---'---'---'-------''' ++ +
Layout b) is modelled by pointing at the Use[] array.
++.-------... +| User +'-------''' + | + v + .---.---.---.---... + | P | P | P | P | + '---'---'---'---''' ++
+Since the Use objects are deprived of the direct (back)pointer to +their User objects, there must be a fast and exact method to +recover it. This is accomplished by the following scheme:
++Given a Use*, all we have to do is to walk till we get +a stop and we either have a User immediately behind or +we have to walk to the next stop picking up digits +and calculating the offset:
++.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---------------- +| 1 | s | 1 | 0 | 1 | 0 | s | 1 | 1 | 0 | s | 1 | 1 | s | 1 | S | User (or User*) +'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---------------- + |+15 |+10 |+6 |+3 |+1 + | | | | |__> + | | | |__________> + | | |______________________> + | |______________________________________> + |__________________________________________________________> ++
+Only the significant number of bits need to be stored between the +stops, so that the worst case is 20 memory accesses when there are +1000 Use objects associated with a User.
+ + + + ++The following literate Haskell fragment demonstrates the concept:
++> import Test.QuickCheck +> +> digits :: Int -> [Char] -> [Char] +> digits 0 acc = '0' : acc +> digits 1 acc = '1' : acc +> digits n acc = digits (n `div` 2) $ digits (n `mod` 2) acc +> +> dist :: Int -> [Char] -> [Char] +> dist 0 [] = ['S'] +> dist 0 acc = acc +> dist 1 acc = let r = dist 0 acc in 's' : digits (length r) r +> dist n acc = dist (n - 1) $ dist 1 acc +> +> takeLast n ss = reverse $ take n $ reverse ss +> +> test = takeLast 40 $ dist 20 [] +> ++
+Printing <test> gives: "1s100000s11010s10100s1111s1010s110s11s1S"
++The reverse algorithm computes the length of the string just by examining +a certain prefix:
+ ++> pref :: [Char] -> Int +> pref "S" = 1 +> pref ('s':'1':rest) = decode 2 1 rest +> pref (_:rest) = 1 + pref rest +> +> decode walk acc ('0':rest) = decode (walk + 1) (acc * 2) rest +> decode walk acc ('1':rest) = decode (walk + 1) (acc * 2 + 1) rest +> decode walk acc _ = walk + acc +> ++
+Now, as expected, printing <pref test> gives 40.
++We can quickCheck this with following property:
+ ++> testcase = dist 2000 [] +> testcaseLength = length testcase +> +> identityProp n = n > 0 && n <= testcaseLength ==> length arr == pref arr +> where arr = takeLast n testcase +> ++
+As expected <quickCheck identityProp> gives:
+ ++*Main> quickCheck identityProp +OK, passed 100 tests. ++
+Let's be a bit more exhaustive:
+ ++> +> deepCheck p = check (defaultConfig { configMaxTest = 500 }) p +> ++
+And here is the result of <deepCheck identityProp>:
+ ++*Main> deepCheck identityProp +OK, passed 500 tests. ++ + + + +
+To maintain the invariant that the 2 LSBits of each Use** in Use +never change after being set up, setters of Use::Prev must re-tag the +new Use** on every modification. Accordingly getters must strip the +tag bits.
++For layout b) instead of the User we find a pointer (User* with LSBit set). +Following this pointer brings us to the User. A portable trick ensures +that the first bytes of User (if interpreted as a pointer) never has +the LSBit set.
+ +