1. At a computer system including system memory, a method for optimizing the execution of a software procedure, the method comprising the acts of: accessing an executable procedure that includes a plurality of different code blocks each of which is instrumented to provide a count for each time the code block is executed during the procedure; generating a hierarchical block graph in which each block is linked to one or more preceding or following blocks based on the original executable order for performing the procedure using the code blocks, and each code block being identified in the hierarchy by its corresponding count; creating one or more code block chains, each chain comprising one or more code blocks for the executable procedure, each said chain being formed by: selecting, in order from highest count to lowest count, each code block in the plurality of code blocks and for each selected code block performing the steps of: when the selected each code block is either a predecessor or a successor to an existing chain, assigning the selected code block to the respective existing chain, otherwise, creating a new chain with the selected each code block; from all existing and created code block chains, identifying code block chains that contain code blocks having non-zero count blocks and chains that contain only code blocks having a zero count; generating a plurality of after sets, each after set indicating a preference that a specified code block chain comes after each code block chain in the each after set in a total ordering; generating a plurality of before sets, each before set indicating a preference that a specified code block chain comes before each code block chain in the each before set in a total ordering; based on the before and after sets, generating precedence relationships that are used to determine how to order the code block chains, with the result that code block chains containing code blocks with higher counts will be given a higher order for execution when executing the procedure than chains containing code blocks with lower counts; and ordering the one or more non-zero code block chains based on the precedence relationships, and then appending any zero-count code block chains at the end of the order, and then storing the ordered code block chains in system memory to optimize subsequent execution of the executable procedure.