aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-04-16 16:28:59 +0000
committerDuncan Sands <baldrick@free.fr>2012-04-16 16:28:59 +0000
commit8883c43ddc13e5f92ba8dfe00f2116a153a570d5 (patch)
tree40b5bad6be11275bb56cb7f227d1e4ee6544718d /include
parent9e67db4af13abb967cae5858502207a43d26bf84 (diff)
downloadexternal_llvm-8883c43ddc13e5f92ba8dfe00f2116a153a570d5.zip
external_llvm-8883c43ddc13e5f92ba8dfe00f2116a153a570d5.tar.gz
external_llvm-8883c43ddc13e5f92ba8dfe00f2116a153a570d5.tar.bz2
Make it possible to indicate relaxed floating point requirements at the IR level
through the use of 'fpmath' metadata. Currently this only provides a 'fpaccuracy' value, which may be a number in ULPs or the keyword 'fast', however the intent is that this will be extended with additional information about NaN's, infinities etc later. No optimizations have been hooked up to this so far. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154822 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Operator.h30
-rw-r--r--include/llvm/Support/IRBuilder.h87
-rw-r--r--include/llvm/Support/MDBuilder.h62
3 files changed, 132 insertions, 47 deletions
diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h
index 9268d98..6bd7e56 100644
--- a/include/llvm/Operator.h
+++ b/include/llvm/Operator.h
@@ -15,8 +15,9 @@
#ifndef LLVM_OPERATOR_H
#define LLVM_OPERATOR_H
-#include "llvm/Instruction.h"
#include "llvm/Constants.h"
+#include "llvm/Instruction.h"
+#include "llvm/Type.h"
namespace llvm {
@@ -162,7 +163,32 @@ public:
(isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
}
};
-
+
+/// FPMathOperator - Utility class for floating point operations which can have
+/// information about relaxed accuracy requirements attached to them.
+class FPMathOperator : public Operator {
+private:
+ ~FPMathOperator(); // do not implement
+
+public:
+
+ /// \brief Get the maximum error permitted by this operation in ULPs. An
+ /// accuracy of 0.0 means that the operation should be performed with the
+ /// default precision. A huge value is returned if the accuracy is 'fast'.
+ float getFPAccuracy() const;
+
+ /// \brief Return true if the accuracy is 'fast'. This indicates that speed
+ /// is more important than accuracy.
+ bool isFastFPAccuracy() const;
+
+ static inline bool classof(const FPMathOperator *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getType()->isFPOrFPVectorTy();
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
/// ConcreteOperator - A helper template for defining operators for individual
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index 7828001..ef00e8e 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -17,6 +17,7 @@
#include "llvm/Instructions.h"
#include "llvm/BasicBlock.h"
+#include "llvm/LLVMContext.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -331,49 +332,63 @@ template<bool preserveNames = true, typename T = ConstantFolder,
typename Inserter = IRBuilderDefaultInserter<preserveNames> >
class IRBuilder : public IRBuilderBase, public Inserter {
T Folder;
+ MDNode *DefaultFPMathTag;
public:
- IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter())
- : IRBuilderBase(C), Inserter(I), Folder(F) {
+ IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(),
+ MDNode *FPMathTag = 0)
+ : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) {
}
- explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder() {
+ explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C),
+ Folder(), DefaultFPMathTag(FPMathTag) {
}
- explicit IRBuilder(BasicBlock *TheBB, const T &F)
- : IRBuilderBase(TheBB->getContext()), Folder(F) {
+ explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(F),
+ DefaultFPMathTag(FPMathTag) {
SetInsertPoint(TheBB);
}
- explicit IRBuilder(BasicBlock *TheBB)
- : IRBuilderBase(TheBB->getContext()), Folder() {
+ explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(),
+ DefaultFPMathTag(FPMathTag) {
SetInsertPoint(TheBB);
}
- explicit IRBuilder(Instruction *IP)
- : IRBuilderBase(IP->getContext()), Folder() {
+ explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0)
+ : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
SetInsertPoint(IP);
SetCurrentDebugLocation(IP->getDebugLoc());
}
- explicit IRBuilder(Use &U)
- : IRBuilderBase(U->getContext()), Folder() {
+ explicit IRBuilder(Use &U, MDNode *FPMathTag = 0)
+ : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
SetInsertPoint(U);
SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
}
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F)
- : IRBuilderBase(TheBB->getContext()), Folder(F) {
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F,
+ MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(F),
+ DefaultFPMathTag(FPMathTag) {
SetInsertPoint(TheBB, IP);
}
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP)
- : IRBuilderBase(TheBB->getContext()), Folder() {
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(),
+ DefaultFPMathTag(FPMathTag) {
SetInsertPoint(TheBB, IP);
}
/// getFolder - Get the constant folder being used.
const T &getFolder() { return Folder; }
+ /// getDefaultFPMathTag - Get the floating point math metadata being used.
+ MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
+
+ /// SetDefaultFPMathTag - Set the floating point math metadata to be used.
+ void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
+
/// isNamePreserving - Return true if this builder is configured to actually
/// add the requested names to IR created through it.
bool isNamePreserving() const { return preserveNames; }
@@ -496,6 +511,14 @@ private:
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
+
+ Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const {
+ if (!FPMathTag)
+ FPMathTag = DefaultFPMathTag;
+ if (FPMathTag)
+ I->setMetadata(LLVMContext::MD_fpmath, FPMathTag);
+ return I;
+ }
public:
Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
bool HasNUW = false, bool HasNSW = false) {
@@ -511,11 +534,13 @@ public:
Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateAdd(LHS, RHS, Name, true, false);
}
- Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFAdd(LC, RC), Name);
- return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name);
+ return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS),
+ FPMathTag), Name);
}
Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
bool HasNUW = false, bool HasNSW = false) {
@@ -531,11 +556,13 @@ public:
Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateSub(LHS, RHS, Name, true, false);
}
- Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFSub(LC, RC), Name);
- return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name);
+ return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS),
+ FPMathTag), Name);
}
Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
bool HasNUW = false, bool HasNSW = false) {
@@ -551,11 +578,13 @@ public:
Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateMul(LHS, RHS, Name, true, false);
}
- Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFMul(LC, RC), Name);
- return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
+ return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS),
+ FPMathTag), Name);
}
Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
bool isExact = false) {
@@ -581,11 +610,13 @@ public:
Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
return CreateSDiv(LHS, RHS, Name, true);
}
- Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFDiv(LC, RC), Name);
- return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name);
+ return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS),
+ FPMathTag), Name);
}
Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
@@ -599,11 +630,13 @@ public:
return Insert(Folder.CreateSRem(LC, RC), Name);
return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
}
- Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "") {
+ Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Insert(Folder.CreateFRem(LC, RC), Name);
- return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name);
+ return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS),
+ FPMathTag), Name);
}
Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
@@ -729,10 +762,10 @@ public:
Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
return CreateNeg(V, Name, true, false);
}
- Value *CreateFNeg(Value *V, const Twine &Name = "") {
+ Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) {
if (Constant *VC = dyn_cast<Constant>(V))
return Insert(Folder.CreateFNeg(VC), Name);
- return Insert(BinaryOperator::CreateFNeg(V), Name);
+ return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name);
}
Value *CreateNot(Value *V, const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
diff --git a/include/llvm/Support/MDBuilder.h b/include/llvm/Support/MDBuilder.h
index 022e8e3..f6d8452 100644
--- a/include/llvm/Support/MDBuilder.h
+++ b/include/llvm/Support/MDBuilder.h
@@ -26,20 +26,46 @@ namespace llvm {
class MDBuilder {
LLVMContext &Context;
+ MDString *getFastString() {
+ return createString("fast");
+ }
public:
MDBuilder(LLVMContext &context) : Context(context) {}
- /// CreateString - Return the given string as metadata.
- MDString *CreateString(StringRef Str) {
+ /// \brief Return the given string as metadata.
+ MDString *createString(StringRef Str) {
return MDString::get(Context, Str);
}
//===------------------------------------------------------------------===//
+ // FPMath metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata with appropriate settings for 'fast math'.
+ MDNode *createFastFPMath() {
+ return MDNode::get(Context, getFastString());
+ }
+
+ /// \brief Return metadata with the given settings. Special values for the
+ /// Accuracy parameter are 0.0, which means the default (maximal precision)
+ /// setting; and negative values which all mean 'fast'.
+ MDNode *createFPMath(float Accuracy) {
+ if (Accuracy == 0.0)
+ return 0;
+ if (Accuracy < 0.0)
+ return MDNode::get(Context, getFastString());
+ assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
+ Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy);
+ return MDNode::get(Context, Op);
+ }
+
+
+ //===------------------------------------------------------------------===//
// Range metadata.
//===------------------------------------------------------------------===//
- /// CreateRange - Return metadata describing the range [Lo, Hi).
- MDNode *CreateRange(const APInt &Lo, const APInt &Hi) {
+ /// \brief Return metadata describing the range [Lo, Hi).
+ MDNode *createRange(const APInt &Lo, const APInt &Hi) {
assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
// If the range is everything then it is useless.
if (Hi == Lo)
@@ -56,10 +82,10 @@ namespace llvm {
// TBAA metadata.
//===------------------------------------------------------------------===//
- /// CreateAnonymousTBAARoot - Return metadata appropriate for a TBAA root
- /// node. Each returned node is distinct from all other metadata and will
- /// never be identified (uniqued) with anything else.
- MDNode *CreateAnonymousTBAARoot() {
+ /// \brief Return metadata appropriate for a TBAA root node. Each returned
+ /// node is distinct from all other metadata and will never be identified
+ /// (uniqued) with anything else.
+ MDNode *createAnonymousTBAARoot() {
// To ensure uniqueness the root node is self-referential.
MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>());
MDNode *Root = MDNode::get(Context, Dummy);
@@ -74,23 +100,23 @@ namespace llvm {
return Root;
}
- /// CreateTBAARoot - Return metadata appropriate for a TBAA root node with
- /// the given name. This may be identified (uniqued) with other roots with
- /// the same name.
- MDNode *CreateTBAARoot(StringRef Name) {
- return MDNode::get(Context, CreateString(Name));
+ /// \brief Return metadata appropriate for a TBAA root node with the given
+ /// name. This may be identified (uniqued) with other roots with the same
+ /// name.
+ MDNode *createTBAARoot(StringRef Name) {
+ return MDNode::get(Context, createString(Name));
}
- /// CreateTBAANode - Return metadata for a non-root TBAA node with the given
- /// name, parent in the TBAA tree, and value for 'pointsToConstantMemory'.
- MDNode *CreateTBAANode(StringRef Name, MDNode *Parent,
+ /// \brief Return metadata for a non-root TBAA node with the given name,
+ /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
+ MDNode *createTBAANode(StringRef Name, MDNode *Parent,
bool isConstant = false) {
if (isConstant) {
Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
- Value *Ops[3] = { CreateString(Name), Parent, Flags };
+ Value *Ops[3] = { createString(Name), Parent, Flags };
return MDNode::get(Context, Ops);
} else {
- Value *Ops[2] = { CreateString(Name), Parent };
+ Value *Ops[2] = { createString(Name), Parent };
return MDNode::get(Context, Ops);
}
}