- // Peephole optimize the following instructions:
- // %t1 = cast ulong <const int> to {<...>} *
- // %t2 = add {<...>} * %SP, %t1 ;; Constant must be 2nd operand
- //
- // or
- // %t1 = cast {<...>}* %SP to int*
- // %t5 = cast ulong <const int> to int*
- // %t2 = add int* %t1, %t5 ;; int is same size as field
- //
- // Into: %t3 = getelementptr {<...>} * %SP, <element indices>
- // %t2 = cast <eltype> * %t3 to {<...>}*
- //
- Value *AddOp1 = I->getOperand(0);
- CastInst *AddOp2 = cast<CastInst>(I->getOperand(1));
- ConstPoolUInt *OffsetV = dyn_cast<ConstPoolUInt>(AddOp2->getOperand(0));
- unsigned Offset = OffsetV ? OffsetV->getValue() : 0;
- Value *SrcPtr; // Of type pointer to struct...
- const StructType *StructTy;
-
- if ((StructTy = getPointedToStruct(AddOp1->getType()))) {
- SrcPtr = AddOp1; // Handle the first case...
- } else if (CastInst *AddOp1c = dyn_cast<CastInst>(AddOp1)) {
- SrcPtr = AddOp1c->getOperand(0); // Handle the second case...
- StructTy = getPointedToStruct(SrcPtr->getType());
- }
-
- // Only proceed if we have detected all of our conditions successfully...
- if (Offset && StructTy && SrcPtr && Offset < TD.getTypeSize(StructTy)) {
- const StructLayout *SL = TD.getStructLayout(StructTy);
- vector<ConstPoolVal*> Offsets;
- unsigned ActualOffset = Offset;
- const Type *ElTy = getStructOffsetType(StructTy, ActualOffset, Offsets);
-
- if (getPointedToStruct(AddOp1->getType())) { // case 1
- PRINT_PEEPHOLE2("add-to-gep1:in", AddOp2, I);
- } else {
- PRINT_PEEPHOLE3("add-to-gep2:in", AddOp1, AddOp2, I);
- }
-
- GetElementPtrInst *GEP = new GetElementPtrInst(SrcPtr, Offsets);
- //AddOp2->getName());
- BI = BB->getInstList().insert(BI, GEP)+1;
-
- assert(Offset-ActualOffset == 0 &&
- "GEP to middle of element not implemented yet!");
-
- ReplaceInstWithInst(BB->getInstList(), BI,
- I = new CastInst(GEP, I->getType()));
- PRINT_PEEPHOLE2("add-to-gep:out", GEP, I);