Question: How do you prevent Code Generation:-IntermediateCode from converting abs() during optimize=tryhard?

I have been writing a language translator. I have everything working reasonably well except that when translating abs(expr) with optimize=tryhard, the IntermediateCode converts the abs() into if...then...else statements. This would be fine except the type of the expr is generally a complex number. I need to optimize the code because there is a lot of redundant calculations otherwise.

I can't figure out how to get IntermediateCode from breaking the abs function into if...then...else statements. [My solution so far is to substitute abs with a dummy name and then use the translator to translate the dummy name into an abs statement - That's really not how things should work!]

Any suggestions?

I've included some example test cases of what is going wrong.

with(CodeGeneration)

testproc1 := proc (x) abs(x) end proc

IntermediateCode(testproc1, optimize = tryhard)

Scope( nametab,
  AssignedName(Name("testproc1"), Scope( nametab,
    Procedure(
      ParameterSequence(Declaration(Name("x"), Type(integer))),
      LocalSequence(Declaration(Name("s1"), Type(integer))),
      OptionSequence(),
      ExpressionSequence(),
      StatementSequence(
        If(
          ConditionalPair(LessEqual(Integer(0), Name("x")), StatementSequence(
            Assignment(Name("s1"), Name("x"))
          )),
          ConditionalPair(Less(Name("x"), Integer(0)), StatementSequence(
            Assignment(Name("s1"), Negation(Name("x")))
          )),
          StatementSequence(
            Assignment(Name("s1"), Integer(0))
          )
        ),
        Return(Name("s1"))
      ),
      DescriptionSequence(),
      GlobalSequence(),
      LexicalSequence(),
      Type(integer)
    )
  ))
)

 

testproc2 := proc (x::numeric) abs(x) end proc

IntermediateCode(testproc2, optimize = tryhard)

Scope( nametab,
  AssignedName(Name("testproc2"), Scope( nametab,
    Procedure(
      ParameterSequence(Declaration(Name("x"), Type(numeric))),
      LocalSequence(Declaration(Name("s1"), Type(numeric))),
      OptionSequence(),
      ExpressionSequence(),
      StatementSequence(
        If(
          ConditionalPair(LessEqual(Float(0, 0), Name("x")), StatementSequence(
            Assignment(Name("s1"), Name("x"))
          )),
          ConditionalPair(Less(Name("x"), Float(0, 0)), StatementSequence(
            Assignment(Name("s1"), Negation(Name("x")))
          )),
          StatementSequence(
            Assignment(Name("s1"), Float(0, 0))
          )
        ),
        Return(Name("s1"))
      ),
      DescriptionSequence(),
      GlobalSequence(),
      LexicalSequence(),
      Type(numeric)
    )
  ))
)

 

NULL

testproc3 := proc (x::complex) abs(x) end proc

IntermediateCode(testproc3, optimize = tryhard)

Scope( nametab,
  AssignedName(Name("testproc3"), Scope( nametab,
    Procedure(
      ParameterSequence(Declaration(Name("x"), Type(complex))),
      LocalSequence(),
      OptionSequence(),
      ExpressionSequence(),
      StatementSequence(
        Return(FunctionCall(Name("abs"), ExpressionSequence(Name("x")), unknown))
      ),
      DescriptionSequence(),
      GlobalSequence(),
      LexicalSequence(),
      Type(numeric)
    )
  ))
)

 

NULL

Download intermediate_code_abs.mw

Please Wait...