Elsa and LLVM and LLVM submissions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Elsa and LLVM and LLVM submissions

Richard Pennington-2
Hi,

I've been writing an Elsa to LLVM interface.
It has been going very well, I think both sets of software are very nice.
At this point I've been able to compile and run a small program (sieve.c).
I've also compiled a pretty complete version of printf(). (It seemed like
a good choice because it touches many data types, varargs, etc.)

I've had to make quite a few changes to Elsa to get this going, but so far
I haven't had to touch LLVM.

I got the current version of LLVM via svn yesterday and modified my code to
use the LLVMFoldingBuilder. Very nice!

My question is this: I noticed that the folding builder doesn't fold some
operations, e.g. casts. Is there some reason why? If I implemented some of
these unhandled cases could I sumbit the changes back to the LLVM project?

-Rich


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Elsa and LLVM and LLVM submissions

Devang Patel

On Dec 15, 2007, at 12:15 PM, Richard Pennington wrote:

> I got the current version of LLVM via svn yesterday and modified my  
> code to
> use the LLVMFoldingBuilder. Very nice!
>
> My question is this: I noticed that the folding builder doesn't fold  
> some
> operations, e.g. casts. Is there some reason why? If I implemented  
> some of
> these unhandled cases could I sumbit the changes back to the LLVM  
> project?

Sure. Though, I do not exactly understand what do you mean by folding  
casts operations, we encourage patches to improve LLVMFoldingBuilder!

-
Devang
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Elsa and LLVM and LLVM submissions

Richard Pennington
Devang Patel wrote:

> On Dec 15, 2007, at 12:15 PM, Richard Pennington wrote:
>
>> I got the current version of LLVM via svn yesterday and modified my  
>> code to
>> use the LLVMFoldingBuilder. Very nice!
>>
>> My question is this: I noticed that the folding builder doesn't fold  
>> some
>> operations, e.g. casts. Is there some reason why? If I implemented  
>> some of
>> these unhandled cases could I sumbit the changes back to the LLVM  
>> project?
>
> Sure. Though, I do not exactly understand what do you mean by folding  
> casts operations, we encourage patches to improve LLVMFoldingBuilder!
>
> -
> Devang
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
Hi Devang,

Folding a cast is like folding any other operator: If the operand is
constant, the cast can be done at compile time. I've made the necessary
changes to LLVMFoldingBuilder.h to handle casts and several other operators.

I have attached the patch. There is one glaring thing that should be
addressed. The #ifdef RICH around code in CreateGEP is there because I'm
not familiar with STL enough to figure out how to get an array of
pointers out of a vector. :-( If someone could clue me in as to the best
way to do this, I'd greatly appreciate it.

I've tested this code with my Elsa->LLVM stuff and also recompiled the
LLVM itself, so I'm pretty confident that the patch doesn't break anything.

Since this is my first patch to LLVM and I've only been using LLVM for
two weeks, please be gentle with me. If I made any glaring submission
errors, I'll gladly fix them.

-Rich

Index: include/llvm/Support/LLVMBuilder.h
===================================================================
--- include/llvm/Support/LLVMBuilder.h (revision 505)
+++ include/llvm/Support/LLVMBuilder.h (working copy)
@@ -538,6 +538,95 @@
   }
   
   //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Memory Instructions
+  //===--------------------------------------------------------------------===//
+  
+  template<typename InputIterator>
+  Value *CreateGEP(Value *Ptr, InputIterator IdxBegin,
+                               InputIterator IdxEnd, const char *Name = "") {
+#if RICH
+    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+        // Every index must be constant.
+        InputIterator i;
+        for (i = IdxBegin; i < IdxEnd; ++i) {
+  if (!dyn_cast<Constant>(*i)) {
+      break;
+  }
+ }
+        if (i == IdxEnd) {
+          return ConstantExpr::getGetElementPtr(PC, &IdxBegin, IdxEnd - IdxBegin);
+ }
+    }
+#endif
+    return LLVMBuilder::CreateGEP(Ptr, IdxBegin, IdxEnd, Name);
+  }
+  Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      if (Constant *IC = dyn_cast<Constant>(Idx))
+        return ConstantExpr::getGetElementPtr(PC, &IC, 1);
+    return LLVMBuilder::CreateGEP(Ptr, Idx, Name);
+  }
+  
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Cast/Conversion Operators
+  //===--------------------------------------------------------------------===//
+  
+  Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") {
+    return CreateCast(Instruction::Trunc, V, DestTy, Name);
+  }
+  Value *CreateZExt(Value *V, const Type *DestTy, const char *Name = "") {
+    return CreateCast(Instruction::ZExt, V, DestTy, Name);
+  }
+  Value *CreateSExt(Value *V, const Type *DestTy, const char *Name = "") {
+    return CreateCast(Instruction::SExt, V, DestTy, Name);
+  }
+  Value *CreateFPToUI(Value *V, const Type *DestTy, const char *Name = ""){
+    return CreateCast(Instruction::FPToUI, V, DestTy, Name);
+  }
+  Value *CreateFPToSI(Value *V, const Type *DestTy, const char *Name = ""){
+    return CreateCast(Instruction::FPToSI, V, DestTy, Name);
+  }
+  Value *CreateUIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+    return CreateCast(Instruction::UIToFP, V, DestTy, Name);
+  }
+  Value *CreateSIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+    return CreateCast(Instruction::SIToFP, V, DestTy, Name);
+  }
+  Value *CreateFPTrunc(Value *V, const Type *DestTy,
+                             const char *Name = "") {
+    return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
+  }
+  Value *CreateFPExt(Value *V, const Type *DestTy, const char *Name = "") {
+    return CreateCast(Instruction::FPExt, V, DestTy, Name);
+  }
+  Value *CreatePtrToInt(Value *V, const Type *DestTy,
+                               const char *Name = "") {
+    return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
+  }
+  Value *CreateIntToPtr(Value *V, const Type *DestTy,
+                               const char *Name = "") {
+    return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
+  }
+  Value *CreateBitCast(Value *V, const Type *DestTy,
+                             const char *Name = "") {
+    return CreateCast(Instruction::BitCast, V, DestTy, Name);
+  }
+  
+  Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
+                       const char *Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return ConstantExpr::getCast(Op, VC, DestTy);
+    return LLVMBuilder::CreateCast(Op, V, DestTy, Name);
+  }
+  Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
+                          const char *Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return ConstantExpr::getIntegerCast(VC, DestTy, isSigned);
+    return LLVMBuilder::CreateIntCast(V, DestTy, isSigned, Name);
+  }
+  
+  
+  //===--------------------------------------------------------------------===//
   // Instruction creation methods: Compare Instructions
   //===--------------------------------------------------------------------===//
   
@@ -630,6 +719,45 @@
         return ConstantExpr::getCompare(P, LC, RC);
     return LLVMBuilder::CreateFCmp(P, LHS, RHS, Name);
   }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Other Instructions
+  //===--------------------------------------------------------------------===//
+  
+  Value *CreateSelect(Value *C, Value *True, Value *False,
+                           const char *Name = "") {
+    if (Constant *CC = dyn_cast<Constant>(C))
+      if (Constant *TC = dyn_cast<Constant>(True))
+        if (Constant *FC = dyn_cast<Constant>(False))
+          return ConstantExpr::getSelect(CC, TC, FC);
+    return LLVMBuilder::CreateSelect(C, True, False, Name);
+  }
+  
+  Value *CreateExtractElement(Value *Vec, Value *Idx,
+                                           const char *Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(Vec))
+      if (Constant *IC = dyn_cast<Constant>(Idx))
+         return ConstantExpr::getExtractElement(VC, IC);
+    return LLVMBuilder::CreateExtractElement(Vec, Idx, Name);
+  }
+  
+  Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
+                                         const char *Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(Vec))
+      if (Constant *NC = dyn_cast<Constant>(NewElt))
+        if (Constant *IC = dyn_cast<Constant>(Idx))
+          return ConstantExpr::getInsertElement(VC, NC, IC);
+    return LLVMBuilder::CreateInsertElement(Vec, NewElt, Idx, Name);
+  }
+  
+  Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
+                                         const char *Name = "") {
+    if (Constant *V1C = dyn_cast<Constant>(V1))
+      if (Constant *V2C = dyn_cast<Constant>(V2))
+        if (Constant *MC = dyn_cast<Constant>(Mask))
+          return ConstantExpr::getShuffleVector(V1C, V2C, MC);
+    return LLVMBuilder::CreateShuffleVector(V1, V2, Mask, Name);
+  }
 };
   
 }

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Elsa and LLVM and LLVM submissions

Devang Patel
I used &Idx[0]. In future, please avoid tabs in your patch.

I applied your patch.
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071217/056403.html
-
Devang

On Dec 17, 2007, at 2:57 AM, Richard Pennington wrote:

> Devang Patel wrote:
>> On Dec 15, 2007, at 12:15 PM, Richard Pennington wrote:
>>> I got the current version of LLVM via svn yesterday and modified  
>>> my  code to
>>> use the LLVMFoldingBuilder. Very nice!
>>>
>>> My question is this: I noticed that the folding builder doesn't  
>>> fold  some
>>> operations, e.g. casts. Is there some reason why? If I  
>>> implemented  some of
>>> these unhandled cases could I sumbit the changes back to the LLVM  
>>> project?
>> Sure. Though, I do not exactly understand what do you mean by  
>> folding  casts operations, we encourage patches to improve  
>> LLVMFoldingBuilder!
>> -
>> Devang
>> _______________________________________________
>> LLVM Developers mailing list
>> [hidden email]         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
> Hi Devang,
>
> Folding a cast is like folding any other operator: If the operand is  
> constant, the cast can be done at compile time. I've made the  
> necessary changes to LLVMFoldingBuilder.h to handle casts and  
> several other operators.
>
> I have attached the patch. There is one glaring thing that should be  
> addressed. The #ifdef RICH around code in CreateGEP is there because  
> I'm not familiar with STL enough to figure out how to get an array  
> of pointers out of a vector. :-( If someone could clue me in as to  
> the best way to do this, I'd greatly appreciate it.
>
> I've tested this code with my Elsa->LLVM stuff and also recompiled  
> the LLVM itself, so I'm pretty confident that the patch doesn't  
> break anything.
>
> Since this is my first patch to LLVM and I've only been using LLVM  
> for two weeks, please be gentle with me. If I made any glaring  
> submission errors, I'll gladly fix them.
>
> -Rich
> Index: include/llvm/Support/LLVMBuilder.h
> ===================================================================
> --- include/llvm/Support/LLVMBuilder.h (revision 505)
> +++ include/llvm/Support/LLVMBuilder.h (working copy)
> @@ -538,6 +538,95 @@
>   }
>
>   //
> =
> =
> =--------------------------------------------------------------------
> ===//
> +  // Instruction creation methods: Memory Instructions
> +  //
> =
> =
> =--------------------------------------------------------------------
> ===//
> +
> +  template<typename InputIterator>
> +  Value *CreateGEP(Value *Ptr, InputIterator IdxBegin,
> +                               InputIterator IdxEnd, const char  
> *Name = "") {
> +#if RICH
> +    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
> +        // Every index must be constant.
> +        InputIterator i;
> +        for (i = IdxBegin; i < IdxEnd; ++i) {
> +  if (!dyn_cast<Constant>(*i)) {
> +      break;
> +  }
> + }
> +        if (i == IdxEnd) {
> +          return ConstantExpr::getGetElementPtr(PC, &IdxBegin,  
> IdxEnd - IdxBegin);
> + }
> +    }
> +#endif
> +    return LLVMBuilder::CreateGEP(Ptr, IdxBegin, IdxEnd, Name);
> +  }
> +  Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
> +    if (Constant *PC = dyn_cast<Constant>(Ptr))
> +      if (Constant *IC = dyn_cast<Constant>(Idx))
> +        return ConstantExpr::getGetElementPtr(PC, &IC, 1);
> +    return LLVMBuilder::CreateGEP(Ptr, Idx, Name);
> +  }
> +
> +  //
> =
> =
> =--------------------------------------------------------------------
> ===//
> +  // Instruction creation methods: Cast/Conversion Operators
> +  //
> =
> =
> =--------------------------------------------------------------------
> ===//
> +
> +  Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name  
> = "") {
> +    return CreateCast(Instruction::Trunc, V, DestTy, Name);
> +  }
> +  Value *CreateZExt(Value *V, const Type *DestTy, const char *Name  
> = "") {
> +    return CreateCast(Instruction::ZExt, V, DestTy, Name);
> +  }
> +  Value *CreateSExt(Value *V, const Type *DestTy, const char *Name  
> = "") {
> +    return CreateCast(Instruction::SExt, V, DestTy, Name);
> +  }
> +  Value *CreateFPToUI(Value *V, const Type *DestTy, const char  
> *Name = ""){
> +    return CreateCast(Instruction::FPToUI, V, DestTy, Name);
> +  }
> +  Value *CreateFPToSI(Value *V, const Type *DestTy, const char  
> *Name = ""){
> +    return CreateCast(Instruction::FPToSI, V, DestTy, Name);
> +  }
> +  Value *CreateUIToFP(Value *V, const Type *DestTy, const char  
> *Name = ""){
> +    return CreateCast(Instruction::UIToFP, V, DestTy, Name);
> +  }
> +  Value *CreateSIToFP(Value *V, const Type *DestTy, const char  
> *Name = ""){
> +    return CreateCast(Instruction::SIToFP, V, DestTy, Name);
> +  }
> +  Value *CreateFPTrunc(Value *V, const Type *DestTy,
> +                             const char *Name = "") {
> +    return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
> +  }
> +  Value *CreateFPExt(Value *V, const Type *DestTy, const char *Name  
> = "") {
> +    return CreateCast(Instruction::FPExt, V, DestTy, Name);
> +  }
> +  Value *CreatePtrToInt(Value *V, const Type *DestTy,
> +                               const char *Name = "") {
> +    return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
> +  }
> +  Value *CreateIntToPtr(Value *V, const Type *DestTy,
> +                               const char *Name = "") {
> +    return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
> +  }
> +  Value *CreateBitCast(Value *V, const Type *DestTy,
> +                             const char *Name = "") {
> +    return CreateCast(Instruction::BitCast, V, DestTy, Name);
> +  }
> +
> +  Value *CreateCast(Instruction::CastOps Op, Value *V, const Type  
> *DestTy,
> +                       const char *Name = "") {
> +    if (Constant *VC = dyn_cast<Constant>(V))
> +      return ConstantExpr::getCast(Op, VC, DestTy);
> +    return LLVMBuilder::CreateCast(Op, V, DestTy, Name);
> +  }
> +  Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
> +                          const char *Name = "") {
> +    if (Constant *VC = dyn_cast<Constant>(V))
> +      return ConstantExpr::getIntegerCast(VC, DestTy, isSigned);
> +    return LLVMBuilder::CreateIntCast(V, DestTy, isSigned, Name);
> +  }
> +
> +
> +  //
> =
> =
> =--------------------------------------------------------------------
> ===//
>   // Instruction creation methods: Compare Instructions
>   //
> =
> =
> =--------------------------------------------------------------------
> ===//
>
> @@ -630,6 +719,45 @@
>         return ConstantExpr::getCompare(P, LC, RC);
>     return LLVMBuilder::CreateFCmp(P, LHS, RHS, Name);
>   }
> +
> +  //
> =
> =
> =--------------------------------------------------------------------
> ===//
> +  // Instruction creation methods: Other Instructions
> +  //
> =
> =
> =--------------------------------------------------------------------
> ===//
> +
> +  Value *CreateSelect(Value *C, Value *True, Value *False,
> +                           const char *Name = "") {
> +    if (Constant *CC = dyn_cast<Constant>(C))
> +      if (Constant *TC = dyn_cast<Constant>(True))
> +        if (Constant *FC = dyn_cast<Constant>(False))
> +          return ConstantExpr::getSelect(CC, TC, FC);
> +    return LLVMBuilder::CreateSelect(C, True, False, Name);
> +  }
> +
> +  Value *CreateExtractElement(Value *Vec, Value *Idx,
> +                                           const char *Name = "") {
> +    if (Constant *VC = dyn_cast<Constant>(Vec))
> +      if (Constant *IC = dyn_cast<Constant>(Idx))
> +         return ConstantExpr::getExtractElement(VC, IC);
> +    return LLVMBuilder::CreateExtractElement(Vec, Idx, Name);
> +  }
> +
> +  Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
> +                                         const char *Name = "") {
> +    if (Constant *VC = dyn_cast<Constant>(Vec))
> +      if (Constant *NC = dyn_cast<Constant>(NewElt))
> +        if (Constant *IC = dyn_cast<Constant>(Idx))
> +          return ConstantExpr::getInsertElement(VC, NC, IC);
> +    return LLVMBuilder::CreateInsertElement(Vec, NewElt, Idx, Name);
> +  }
> +
> +  Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
> +                                         const char *Name = "") {
> +    if (Constant *V1C = dyn_cast<Constant>(V1))
> +      if (Constant *V2C = dyn_cast<Constant>(V2))
> +        if (Constant *MC = dyn_cast<Constant>(Mask))
> +          return ConstantExpr::getShuffleVector(V1C, V2C, MC);
> +    return LLVMBuilder::CreateShuffleVector(V1, V2, Mask, Name);
> +  }
> };
>
> }
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-
Devang



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Elsa and LLVM and LLVM submissions

dag-7
On Monday 17 December 2007 13:08, Devang Patel wrote:
> I used &Idx[0]. In future, please avoid tabs in your patch.
>
> I applied your patch.
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20071217/056403
>.html -
> Devang

Devang,

This patch is dangerous:

+  template<typename InputIterator>
+  Value *CreateGEP(Value *Ptr, InputIterator IdxBegin,
+                   InputIterator IdxEnd, const char *Name = "") {
+    
+    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+      // Every index must be constant.
+      InputIterator i;
+      for (i = IdxBegin; i < IdxEnd; ++i)
+        if (!dyn_cast<Constant>(*i))
+          break;
+      if (i == IdxEnd)
+        return ConstantExpr::getGetElementPtr(PC, &IdxBegin[0], IdxEnd -
IdxBegin);

&IdxBegin[0] is a very bad idea.  If idxBegin == IdxEnd this will fault at
best.

The patch also assumes InputIterator is a random-access iterator, which
is true in this case but isn't guaranteed.

It looks like we need some new ConstantExpr::getGetElementPtr interfaces.
It should be a simple matter to copy the implementation of

Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
                                         unsigned NumIdx)

and pass iterators instread.  The implementation would simply forward the
iterators to GetElementPtrInst::getIndexedType which already has the
necessary interfaces that ensure the iterators are random-access.

                                      -Dave

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev