[llvm-commits] [dragonegg] r94978 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h
Duncan Sands
baldrick at free.fr
Mon Feb 1 04:53:02 PST 2010
Author: baldrick
Date: Mon Feb 1 06:53:02 2010
New Revision: 94978
URL: http://llvm.org/viewvc/llvm-project?rev=94978&view=rev
Log:
Factor code.
Modified:
dragonegg/trunk/llvm-convert.cpp
dragonegg/trunk/llvm-internal.h
Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=94978&r1=94977&r2=94978&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Mon Feb 1 06:53:02 2010
@@ -1329,6 +1329,42 @@
return Builder.CreateCast(opcode, V, Ty);
}
+/// CreateAnyAdd - Add two LLVM scalar values with the given GCC type. Does not
+/// support complex numbers. The type is used to set overflow flags.
+Value *TreeToLLVM::CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type) {
+ if (FLOAT_TYPE_P(type))
+ return Builder.CreateFAdd(LHS, RHS);
+ if (TYPE_OVERFLOW_WRAPS(type))
+ return Builder.CreateAdd(LHS, RHS);
+// if (TYPE_UNSIGNED(type))
+// return Builder.CreateNUWAdd(LHS, RHS);
+ return Builder.CreateNSWAdd(LHS, RHS);
+}
+
+/// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
+/// Does not support complex numbers. The type is used to set overflow flags.
+Value *TreeToLLVM::CreateAnyMul(Value *LHS, Value *RHS, tree_node *type) {
+ if (FLOAT_TYPE_P(type))
+ return Builder.CreateFMul(LHS, RHS);
+ if (TYPE_OVERFLOW_WRAPS(type))
+ return Builder.CreateMul(LHS, RHS);
+// if (TYPE_UNSIGNED(type))
+// return Builder.CreateNUWMul(LHS, RHS);
+ return Builder.CreateNSWMul(LHS, RHS);
+}
+
+/// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
+/// Does not support complex numbers. The type is used to set overflow flags.
+Value *TreeToLLVM::CreateAnySub(Value *LHS, Value *RHS, tree_node *type) {
+ if (FLOAT_TYPE_P(type))
+ return Builder.CreateFSub(LHS, RHS);
+ if (TYPE_OVERFLOW_WRAPS(type))
+ return Builder.CreateSub(LHS, RHS);
+// if (TYPE_UNSIGNED(type))
+// return Builder.CreateNUWSub(LHS, RHS);
+ return Builder.CreateNSWSub(LHS, RHS);
+}
+
/// CreateTemporary - Create a new alloca instruction of the specified type,
/// inserting it into the entry block and returning it. The resulting
/// instruction's type is a pointer to the specified type.
@@ -6302,26 +6338,13 @@
Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
// (a+ib) - (c+id) = (a-c) + i(b-d)
- if (LHSr->getType()->isFloatingPoint()) {
- LHSr = Builder.CreateFSub(LHSr, RHSr);
- LHSi = Builder.CreateFSub(LHSi, RHSi);
- } else if (TYPE_OVERFLOW_WRAPS(elt_type)) {
- LHSr = Builder.CreateSub(LHSr, RHSr);
- LHSi = Builder.CreateSub(LHSi, RHSi);
- } else {
- LHSr = Builder.CreateNSWSub(LHSr, RHSr);
- LHSi = Builder.CreateNSWSub(LHSi, RHSi);
- }
+ LHSr = CreateAnySub(LHSr, RHSr, elt_type);
+ LHSi = CreateAnySub(LHSi, RHSi, elt_type);
return CreateComplex(LHSr, LHSi, elt_type);
}
- if (LHS->getType()->isFPOrFPVector())
- return Builder.CreateFSub(LHS, RHS);
- else if (TYPE_OVERFLOW_WRAPS(type))
- return Builder.CreateSub(LHS, RHS);
- else
- return Builder.CreateNSWSub(LHS, RHS);
+ return CreateAnySub(LHS, RHS, type);
}
Value *TreeToLLVM::EmitReg_MULT_EXPR(tree op0, tree op1) {
@@ -6336,7 +6359,7 @@
Value *DSTr, *DSTi;
// (a+ib) * (c+id) = (ac-bd) + i(ad+cb)
- if (LHSr->getType()->isFloatingPoint()) {
+ if (SCALAR_FLOAT_TYPE_P(elt_type)) {
Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c
Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d
DSTr = Builder.CreateFSub(Tmp1, Tmp2); // ac-bd
@@ -6361,12 +6384,7 @@
return CreateComplex(DSTr, DSTi, elt_type);
}
- if (LHS->getType()->isFPOrFPVector())
- return Builder.CreateFMul(LHS, RHS);
- else if (TYPE_OVERFLOW_WRAPS(type))
- return Builder.CreateMul(LHS, RHS);
- else
- return Builder.CreateNSWMul(LHS, RHS);
+ return CreateAnyMul(LHS, RHS, type);
}
Value *TreeToLLVM::EmitReg_PLUS_EXPR(tree op0, tree op1) {
@@ -6380,26 +6398,13 @@
Value *RHSr, *RHSi; SplitComplex(RHS, RHSr, RHSi, elt_type);
// (a+ib) + (c+id) = (a+c) + i(b+d)
- if (LHSr->getType()->isFloatingPoint()) {
- LHSr = Builder.CreateFAdd(LHSr, RHSr);
- LHSi = Builder.CreateFAdd(LHSi, RHSi);
- } else if (TYPE_OVERFLOW_WRAPS(elt_type)) {
- LHSr = Builder.CreateAdd(LHSr, RHSr);
- LHSi = Builder.CreateAdd(LHSi, RHSi);
- } else {
- LHSr = Builder.CreateNSWAdd(LHSr, RHSr);
- LHSi = Builder.CreateNSWAdd(LHSi, RHSi);
- }
+ LHSr = CreateAnyAdd(LHSr, RHSr, elt_type);
+ LHSi = CreateAnyAdd(LHSi, RHSi, elt_type);
return CreateComplex(LHSr, LHSi, elt_type);
}
- if (LHS->getType()->isFPOrFPVector())
- return Builder.CreateFAdd(LHS, RHS);
- else if (TYPE_OVERFLOW_WRAPS(type))
- return Builder.CreateAdd(LHS, RHS);
- else
- return Builder.CreateNSWAdd(LHS, RHS);
+ return CreateAnyAdd(LHS, RHS, type);
}
Value *TreeToLLVM::EmitReg_POINTER_PLUS_EXPR(tree type, tree op0, tree op1) {
@@ -6427,8 +6432,7 @@
Value *DSTr, *DSTi;
// (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
- assert (LHSr->getType()->isFloatingPoint() &&
- "RDIV_EXPR not floating point!");
+ assert (SCALAR_FLOAT_TYPE_P(elt_type) && "RDIV_EXPR not floating point!");
Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c
Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d
Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2); // ac+bd
@@ -6446,7 +6450,7 @@
return CreateComplex(DSTr, DSTi, elt_type);
}
- assert(LHS->getType()->isFPOrFPVector() && "RDIV_EXPR not floating point!");
+ assert(FLOAT_TYPE_P(type) && "RDIV_EXPR not floating point!");
return Builder.CreateFDiv(LHS, RHS);
}
@@ -6547,8 +6551,11 @@
Value *DSTr, *DSTi;
// (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
- assert (LHSr->getType()->isInteger() &&
- "TRUNC_DIV_EXPR not integer!");
+ assert (LHSr->getType()->isInteger() && "TRUNC_DIV_EXPR not integer!");
+ // If overflow does not wrap in the element type then it is tempting to
+ // use NSW operations here. However that would be wrong since overflow
+ // of an intermediate value calculated here does not necessarily imply
+ // that the final result overflows.
Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd
Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=94978&r1=94977&r2=94978&view=diff
==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Mon Feb 1 06:53:02 2010
@@ -473,6 +473,18 @@
/// BitCast, FPTrunc and FPExt.
Value *CastToFPType(Value *V, const Type* Ty);
+ /// CreateAnyAdd - Add two LLVM scalar values with the given GCC type. Does
+ /// not support complex numbers. The type is used to set overflow flags.
+ Value *CreateAnyAdd(Value *LHS, Value *RHS, tree_node *type);
+
+ /// CreateAnyMul - Multiply two LLVM scalar values with the given GCC type.
+ /// Does not support complex numbers. The type is used to set overflow flags.
+ Value *CreateAnyMul(Value *LHS, Value *RHS, tree_node *type);
+
+ /// CreateAnySub - Subtract two LLVM scalar values with the given GCC type.
+ /// Does not support complex numbers.
+ Value *CreateAnySub(Value *LHS, Value *RHS, tree_node *type);
+
/// CreateTemporary - Create a new alloca instruction of the specified type,
/// inserting it into the entry block and returning it. The resulting
/// instruction's type is a pointer to the specified type.
More information about the llvm-commits
mailing list