Main Content

Fold Expressions

Expression folding optimizes code to minimize the computation of intermediate results at block outputs and the storage of such results in temporary buffers or variables. When expression folding is on, the code generator collapses (folds) block computations into a single expression, instead of generating separate code statements and storage declarations for each block in a model. Most Simulink® blocks support expression folding.

Expression folding improves the efficiency of generated code, frequently achieving results that compare favorably to hand-optimized code. In many cases, entire groups of model computations fold into a single, highly optimized line of code.

Example Model

model = 'FoldBlockComputations';
open_system(model);

Generate Code

Expression folding is available only when the Signal storage reuse parameter is set to on because expression folding operates only on expressions involving local variables. The Signal storage reuse and Eliminate superfluous local variables (expression folding) parameters are on by default. Clear the Eliminate superfluous local variables (expression folding) parameter or enter the following command in the MATLAB® Command Window to turn the parameter off:

set_param(model, 'ExpressionFolding','off');

Build the model.

slbuild(model)
### Starting build procedure for: FoldBlockComputations
### Successful completion of build procedure for: FoldBlockComputations

Build Summary

Top model targets built:

Model                  Action                        Rebuild Reason                                    
=======================================================================================================
FoldBlockComputations  Code generated and compiled.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 14.661s

With expression folding off, in the FoldBlockComputations.c file, there are separate code statements before and in the Switch block operation.

cfile = fullfile('FoldBlockComputations_grt_rtw','FoldBlockComputations.c');
coder.example.extractLines(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void FoldBlockComputations_step(void)
{
  real_T rtb_Gain;
  boolean_T rtb_LogicalOperator;
  boolean_T rtb_RelationalOperator;

  /* RelationalOperator: '<Root>/Relational Operator1' incorporates:
   *  Constant: '<Root>/Constant'
   *  Inport: '<Root>/In2'
   */
  rtb_LogicalOperator = (FoldBlockComputations_P.UPPER >=
    FoldBlockComputations_U.In2);

  /* RelationalOperator: '<Root>/Relational Operator' incorporates:
   *  Constant: '<Root>/Constant1'
   *  Inport: '<Root>/In2'
   */
  rtb_RelationalOperator = (FoldBlockComputations_U.In2 <=
    FoldBlockComputations_P.LOWER);

  /* Logic: '<Root>/Logical Operator' */
  rtb_LogicalOperator = (rtb_LogicalOperator || rtb_RelationalOperator);

  /* Switch: '<Root>/Switch' */
  if (rtb_LogicalOperator) {
    /* Gain: '<Root>/Gain' incorporates:
     *  Inport: '<Root>/In1'
     */
    rtb_Gain = 2.0 * FoldBlockComputations_U.In1;

    /* Lookup_n-D: '<Root>/Look-Up Table' incorporates:
     *  Gain: '<Root>/Gain'
     */
    rtb_Gain = look1_binlx(rtb_Gain, FoldBlockComputations_P.T1Break,
      FoldBlockComputations_P.T1Data, 10U);
  } else {
    /* Lookup_n-D: '<Root>/Look-Up Table (2-D)' incorporates:
     *  Inport: '<Root>/In3'
     *  Inport: '<Root>/In4'
     */
    rtb_Gain = look2_binlx(FoldBlockComputations_U.In3,
      FoldBlockComputations_U.In4, FoldBlockComputations_P.T2Break,
      FoldBlockComputations_P.T2Break, FoldBlockComputations_P.T2Data,
      rtCP_LookUpTable2D_maxIndex, 3U);
  }

  /* End of Switch: '<Root>/Switch' */

  /* Outport: '<Root>/Out1' */
  FoldBlockComputations_Y.Out1 = rtb_Gain;
}

Generate Code with Optimization

Enter the following command to turn expression folding on:

set_param(model, 'ExpressionFolding','on');

Build the model.

slbuild(model);
### Starting build procedure for: FoldBlockComputations
### Successful completion of build procedure for: FoldBlockComputations

Build Summary

Top model targets built:

Model                  Action                        Rebuild Reason                   
======================================================================================
FoldBlockComputations  Code generated and compiled.  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 8.8834s

The following is a portion of FoldBlockComputations.c. In the optimized code, the code generator folds all computations into the Switch block operation.

coder.example.extractLines(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void FoldBlockComputations_step(void)
{
  /* Switch: '<Root>/Switch' incorporates:
   *  Constant: '<Root>/Constant'
   *  Constant: '<Root>/Constant1'
   *  Inport: '<Root>/In2'
   *  Logic: '<Root>/Logical Operator'
   *  RelationalOperator: '<Root>/Relational Operator'
   *  RelationalOperator: '<Root>/Relational Operator1'
   */
  if ((FoldBlockComputations_P.UPPER >= FoldBlockComputations_U.In2) ||
      (FoldBlockComputations_U.In2 <= FoldBlockComputations_P.LOWER)) {
    /* Outport: '<Root>/Out1' incorporates:
     *  Gain: '<Root>/Gain'
     *  Inport: '<Root>/In1'
     *  Lookup_n-D: '<Root>/Look-Up Table'
     */
    FoldBlockComputations_Y.Out1 = look1_binlx(2.0 * FoldBlockComputations_U.In1,
      FoldBlockComputations_P.T1Break, FoldBlockComputations_P.T1Data, 10U);
  } else {
    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In3'
     *  Inport: '<Root>/In4'
     *  Lookup_n-D: '<Root>/Look-Up Table (2-D)'
     */
    FoldBlockComputations_Y.Out1 = look2_binlx(FoldBlockComputations_U.In3,
      FoldBlockComputations_U.In4, FoldBlockComputations_P.T2Break,
      FoldBlockComputations_P.T2Break, FoldBlockComputations_P.T2Data,
      rtCP_LookUpTable2D_maxIndex, 3U);
  }

  /* End of Switch: '<Root>/Switch' */
}

Close the model and code generation report.

bdclose(model)