PROBLEM
The problem appears on deeply nested structures due to the getFoldedSizeOf implementation (lib/IR/ConstantFold.cpp), which is very ineffective on such data types.
getFoldedSizeOf runs through the structure's fields to find out if all the fields are of the same size. If the function finds they are of different size, it calls ConstantExpr::getSizeOf with the structure type as an argument. ConstantExpr::getSizeOf internally leads to getFoldedSizeOf call that iterates the structure's fields again calculating structure size.
Since getFoldedSizeOf has recursive nature, the number of its calls grows immensely with structure nesting depth increase. E.g., for the attached structure having nesting depth=21 it is called 31719423 times.
PROPOSED SOLUTION
getFoldedSizeOf is doing the same work twice:
- when iterating the structure's fields to compare field sizes;
- when finally calling ConstantExpr::getSizeOf to calculate structure size.
The idea is to eliminate the 2nd step and calculate the whole size at the 1st step by summarizing sizes of separate fields.
This solution reduces getFoldedSizeOf calls from over 31M to about 80. The structure is processed in a fraction of a second.
Regression and performance tests show no regression.