yuazhang

Hi,

I have another question. If I want to compute the number of Integer (add /sub), Interger(mul/div), and floating point(add/sub), floating(mul/div) , How to do with IR

I mean, I can know the type of the operation, if it is add, sub, multiply or division, but how can I distinguish the integer and floating kind Must I infer it from operands' type If that, then how to decide the operation type based on operands

like: a = c(an int) + b (an float)

thank you very much!

Regards,
Ray

### Re: Phoenix How to distinguish the integer add and floating point add?

Andy Ayers - MSFT

Yes, you need to look at the types.

Phoenix IR does not support mixed operand types on an arithmetic instruction like int + float. So you should never see something like this.

### Re: Phoenix How to distinguish the integer add and floating point add?

yuazhang

Thank you very much!

Now, when I doing it, I met another problem. I want to count the number of integer addition, so first I have to use

if (instruction->Opcode == Phx::Common:pcode::Add) to find out add operations first. However, there are not only 1 add operations, we have: AddOverflowWithCarry, AddWithaCarry, AddWithOverflow....Similiarly, multiply and division, and substract have more than one types too.

If I want to count all add operations, for example, what should I do Does "Add" include all the other type of add operations

Thank you very much!

Regards,
Ray

### Re: Phoenix How to distinguish the integer add and floating point add?

Andy Ayers - MSFT

You'll need to figure out which HIR opcodes belong as part of your notion of addition. It should be pretty straightforward, but you should realize that memory operands can include implicit adds and multiplies: the general form for a memory address is: base + index * scale + offset.

### Re: Phoenix How to distinguish the integer add and floating point add?

yuazhang

Hi Andy,

Thank you for telling me the memory operands issue! Is there any other places that will contain implicit adds and multipiles I mean other type of opcodes

Another thing is, I don't quite understand "which HIR opcodes belong as part of your notion of addtion" mean Does that mean that the add operation in a HIR, should either be "add", or "addwithoverflow" ...... Or a HIR can contain all of those types
Could you explain this a little more in detail

Also, I wrote some codes to count add and sub for integer and float, and did a simple experiment in which I didn't consider the implicit add/mul in the memory operand. I also counted the number of memory access.

for each (insturciont in functionUnit) {

if(instruction->Opcode == Phx::Common:pcode::Add || instruction->Opcode == Phx::Common:pcode:ubtract) {
for each (Phx::IR:perand ^operand in instruction->SourceOperands) {
if (operand->IsFloat){
break;
}
}

for each (Phx::IR:perand ^operand in instruction->SourceAndDestinationOperands)
if (operand->IsMemoryOperand)
mem_access++;

}

And I plug in this code after different phases, "CxxIL Reader", "MIR Lower" and "Lower", and got different results for a function.

HIR 5 2 10
MIR 35 2 10
LIR 0 0 70

The number becomes 0 for add and sub operation in LIR. Is there something wrong with my codes Is it related to the problem of "addwithoverflow" issue

Another general issue is how to know that sub class of opcodes that IR is using after a particular phase, (through Phx::common:pcode::.....), let's say HIR, MIR, LIR for more general case

Thank you very much!

Regards,
Ray

### Re: Phoenix How to distinguish the integer add and floating point add?

yuazhang

Hi Andy,

I have no idea how to count this implicit add and mul in the memory address. Could you give me some simple example codes I mean , I don't know how to use API to do it.

Thank you very much!

Regards,
Ray

### Re: Phoenix How to distinguish the integer add and floating point add?

Andy Ayers - MSFT

Is there any other places that will contain implicit adds and multipiles I mean other type of opcodes

Because HIR is so high-level, an HIR opcode might expand into an entire sequence of operations in MIR or LIR. For example, the MEMCOPY HIR instruction turns into a loop.

I don't quite understand "which HIR opcodes belong as part of your notion of addtion" mean Does that mean that the add operation in a HIR, should either be "add", or "addwithoverflow" ...... Or a HIR can contain all of those types
Could you explain this a little more in detail

The notion of counting specific kinds of operations is not well specified -- that's what I meant by asking for "your notion of addition". I don't really know what you are trying to accomplish by counting operations, so I don't know how to help you do a better job.

Also, I wrote some codes to count add and sub for integer and float, and did a simple experiment in which I didn't consider the implicit add/mul in the memory operand. I also counted the number of memory access.

...code snippet omitted...

And I plug in this code after different phases, "CxxIL Reader", "MIR Lower" and "Lower", and got different results for a function.

HIR 5 2 10
MIR 35 2 10
LIR 0 0 70

The number becomes 0 for add and sub operation in LIR. Is there something wrong with my codes Is it related to the problem of "addwithoverflow" issue

The change from HIR to MIR is not unexpected -- you can look at the IR yourself and see why. As I mentioned above, HIR can be expanded into sequences of MIR, and MIR into sequences of LIR, so the number of operations of a given kind will change. Your plugin fails to work in LIR because the opcodes in LIR are machine specific -- so you need to look for Phx.Targets.Architectures.X86.add for example, instead of Phx.Common.Opcode.ADD.

Another general issue is how to know that sub class of opcodes that IR is using after a particular phase, (through Phx::common: Opcode::.....), let's say HIR, MIR, LIR for more general case

Each opcode has a property that indicates the lowest IR state for which the opcode is legal. So Phx.Common.Opcode.ADD will say it is legal in HIR and MIR but not LIR. You can scan all the opcode tables to collate this information if that helps you any.

I have no idea how to count this implicit add and mul in the memory address. Could you give me some simple example codes I mean , I don't know how to use API to do it.

A memory operand has several optional sub-parts: base, index & scale, and offset. You just need to check for these and account for their impacts. The general form is base + index * scale + offset: 2 adds and one multiply (or shift, since scale is either 1, 2, 4, or maybe 8). So for instance if you find a memory operand with just a base then there are no arithmetic operations needed to form the address; base + offset or base + scale * index has one add and in the latter case a shift/multiply. So code to count the arithmetic would look something like this:

Code Snippet

unsigned int addCount = (memOperand->BaseOperand != nullptr 1 : 0)

+ (memOperand->IndexOperand != nullptr 0 : 1)

+ (memOperand->Offset != 0 1 : 0)

- 1;