Improve codegen for the LLVM offsetof/sizeof "operator". Before we compiled
authorChris Lattner <sabre@nondot.org>
Thu, 15 Jul 2004 00:58:53 +0000 (00:58 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 15 Jul 2004 00:58:53 +0000 (00:58 +0000)
this LLVM function:

int %foo() {
        ret int cast (int** getelementptr (int** null, int 1) to int)
}

into:

foo:
        mov %EAX, 0
        lea %EAX, DWORD PTR [%EAX + 4]
        ret

now we compile it into:

foo:
        mov %EAX, 4
        ret

This sequence is frequently generated by the MSIL front-end, and soon the malloc lowering pass and
Java front-ends as well..

-Chris

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14834 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp

index 5cabd485bd0f989b8d2b4e76faed2f722b63b4b7..68a602b31435d9a81bb8c26accf193632d536289 100644 (file)
@@ -3663,6 +3663,21 @@ void ISel::emitGEPOperation(MachineBasicBlock *MBB,
   if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Src))
     Src = CPR->getValue();
 
+  // If this is a getelementptr null, with all constant integer indices, just
+  // replace it with TargetReg = 42.
+  if (isa<ConstantPointerNull>(Src)) {
+    User::op_iterator I = IdxBegin;
+    for (; I != IdxEnd; ++I)
+      if (!isa<ConstantInt>(*I))
+        break;
+    if (I == IdxEnd) {   // All constant indices
+      unsigned Offset = TD.getIndexedOffset(Src->getType(),
+                                         std::vector<Value*>(IdxBegin, IdxEnd));
+      BuildMI(*MBB, IP, X86::MOV32ri, 1, TargetReg).addImm(Offset);
+      return;
+    }
+  }
+
   std::vector<Value*> GEPOps;
   GEPOps.resize(IdxEnd-IdxBegin+1);
   GEPOps[0] = Src;
index 5cabd485bd0f989b8d2b4e76faed2f722b63b4b7..68a602b31435d9a81bb8c26accf193632d536289 100644 (file)
@@ -3663,6 +3663,21 @@ void ISel::emitGEPOperation(MachineBasicBlock *MBB,
   if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Src))
     Src = CPR->getValue();
 
+  // If this is a getelementptr null, with all constant integer indices, just
+  // replace it with TargetReg = 42.
+  if (isa<ConstantPointerNull>(Src)) {
+    User::op_iterator I = IdxBegin;
+    for (; I != IdxEnd; ++I)
+      if (!isa<ConstantInt>(*I))
+        break;
+    if (I == IdxEnd) {   // All constant indices
+      unsigned Offset = TD.getIndexedOffset(Src->getType(),
+                                         std::vector<Value*>(IdxBegin, IdxEnd));
+      BuildMI(*MBB, IP, X86::MOV32ri, 1, TargetReg).addImm(Offset);
+      return;
+    }
+  }
+
   std::vector<Value*> GEPOps;
   GEPOps.resize(IdxEnd-IdxBegin+1);
   GEPOps[0] = Src;