├── CMakeLists.txt ├── LICENSE.TXT ├── Makefile ├── Makefile.common.in ├── ModuleInfo.txt ├── README ├── Regressions ├── 2006-02-13.ArrayOfObjects.ll ├── 2006-02-23.memcpy.ll ├── 2006-03-04.undefArg.ll ├── 2006-03-05.vaargCall.ll ├── 2006-04-13.MixedAllocaGlobals.ll ├── 2008-09-29.calls.c ├── 2008-09-30.john.ll ├── 2008-10-31.missingECs.ll └── 2009-08-05.packed.ll ├── autoconf ├── AutoRegen.sh ├── aclocal.m4 ├── config.guess ├── config.sub ├── configure.ac ├── install-sh ├── ltmain.sh └── mkinstalldirs ├── configure ├── docs └── dsa-manual │ ├── Makefile │ └── manual.tex ├── include ├── LinkDSA.h ├── LinkPA.h ├── assistDS │ ├── ArgCast.h │ ├── DSNodeEquivs.h │ ├── Devirt.h │ ├── FuncSimplify.h │ ├── FuncSpec.h │ ├── GEPExprArgs.h │ ├── IndCloner.h │ ├── Int2PtrCmp.h │ ├── LoadArgs.h │ ├── MergeGEP.h │ ├── SimplifyExtractValue.h │ ├── SimplifyGEP.h │ ├── SimplifyInsertValue.h │ ├── SimplifyLoad.h │ ├── StructReturnToPointer.h │ ├── TypeChecks.h │ └── TypeChecksOpt.h ├── dsa │ ├── AddressTakenAnalysis.h │ ├── AllocatorIdentification.h │ ├── CallTargets.h │ ├── DSCallGraph.h │ ├── DSGraph.h │ ├── DSGraphTraits.h │ ├── DSNode.h │ ├── DSSupport.h │ ├── DataStructure.h │ ├── EntryPointAnalysis.h │ ├── TypeSafety.h │ ├── keyiterator.h │ ├── stl_util.h │ ├── super_set.h │ └── svset.h ├── poolalloc │ ├── Config │ │ ├── config.h.cmake │ │ └── config.h.in │ ├── Heuristic.h │ ├── MMAPSupport.h │ ├── PoolAllocate.h │ ├── RunTimeAssociate.h │ ├── RuntimeChecks.h │ └── Support │ │ └── MallocAllocator.h └── poolalloc_runtime │ ├── PoolAllocator.h │ ├── Support │ └── SplayTree.h │ └── test.ex ├── lib ├── AssistDS │ ├── ArgCast.cpp │ ├── ArgSimplify.cpp │ ├── CMakeLists.txt │ ├── DSNodeEquivs.cpp │ ├── Devirt.cpp │ ├── DynCount.cpp │ ├── FuncSimplify.cpp │ ├── FuncSpec.cpp │ ├── GEPExprArgs.cpp │ ├── IndCloner.cpp │ ├── Int2PtrCmp.cpp │ ├── LoadArgs.cpp │ ├── Makefile │ ├── MergeGEP.cpp │ ├── SVADevirt.cpp │ ├── SimplifyExtractValue.cpp │ ├── SimplifyGEP.cpp │ ├── SimplifyInsertValue.cpp │ ├── SimplifyLoad.cpp │ ├── StructReturnToPointer.cpp │ ├── TypeChecks.cpp │ └── TypeChecksOpt.cpp ├── CMakeLists.txt ├── DSA │ ├── AddressTakenAnalysis.cpp │ ├── AllocatorIdentification.cpp │ ├── Basic.cpp │ ├── BottomUpClosure.cpp │ ├── CMakeLists.txt │ ├── CallTargets.cpp │ ├── CompleteBottomUp.cpp │ ├── DSCallGraph.cpp │ ├── DSGraph.cpp │ ├── DSTest.cpp │ ├── DataStructure.cpp │ ├── DataStructureStats.cpp │ ├── EntryPointAnalysis.cpp │ ├── EquivClassGraphs.cpp │ ├── GraphChecker.cpp │ ├── Local.cpp │ ├── Makefile │ ├── Printer.cpp │ ├── README │ ├── SanityCheck.cpp │ ├── StdLibPass.cpp │ ├── TopDownClosure.cpp │ └── TypeSafety.cpp ├── Macroscopic │ ├── DeadFieldElimination.cpp │ ├── Makefile │ ├── README.txt │ ├── StructureFieldVisitor.cpp │ └── StructureFieldVisitor.h ├── Makefile └── PoolAllocate │ ├── AccessTrace.cpp │ ├── AllHeapNodesHeuristic.cpp │ ├── AllNodesHeuristic.cpp │ ├── CMakeLists.txt │ ├── Heuristic.cpp │ ├── Makefile │ ├── PAMultipleGlobalPool.cpp │ ├── PASimple.cpp │ ├── PointerCompress.cpp │ ├── PoolAllocate.cpp │ ├── PoolOptimize.cpp │ ├── RunTimeAssociate.cpp │ └── TransformFunctionBody.cpp ├── runtime ├── CMakeLists.txt ├── DynCount │ ├── DynCount.c │ └── Makefile ├── DynamicTypeChecks │ ├── Makefile │ └── TypeRuntime.cpp ├── FL2Allocator │ ├── CMakeLists.txt │ ├── Makefile │ ├── PoolAllocator.cpp │ └── PoolAllocator.h ├── FreeListAllocator │ ├── CMakeLists.txt │ ├── Makefile │ ├── PageManager.cpp │ ├── PageManager.h │ ├── PoolAllocator.cpp │ ├── PoolAllocator.h │ ├── PoolSlab.h │ └── README.txt ├── HeapFrag │ ├── HeapFrag.c │ └── Makefile ├── Makefile ├── PoolAllocator │ ├── Makefile │ ├── PageManager.cpp │ ├── PageManager.h │ ├── PoolAllocator.h │ └── PoolAllocatorBitMask.cpp ├── PreRT │ ├── CMakeLists.txt │ ├── Makefile │ ├── qsort.c │ └── strdup.c └── README.txt ├── test ├── CMakeLists.txt ├── Makefile ├── TEST.FL2.Makefile ├── TEST.FL2.report ├── TEST.calltargets.Makefile ├── TEST.calltargets.report ├── TEST.cputrack.Makefile ├── TEST.cputrack.report ├── TEST.dsaa.Makefile ├── TEST.dsaa.report ├── TEST.dsgraph.Makefile ├── TEST.dsgraph.gnuplot ├── TEST.dsgraph.report ├── TEST.dsprecision.Makefile ├── TEST.dsprecision.report ├── TEST.optzn.Makefile ├── TEST.optzn.report ├── TEST.p4perf.Makefile ├── TEST.p4perf.report ├── TEST.pacompiletime.Makefile ├── TEST.pacompiletime.report ├── TEST.pavtl.Makefile ├── TEST.pavtl.report ├── TEST.perf.Makefile ├── TEST.perf.report ├── TEST.poolalloc.Makefile ├── TEST.poolalloc.report ├── TEST.ptrcomp.Makefile ├── TEST.ptrcomp.report ├── TEST.strace.Makefile ├── TEST.types.Makefile ├── TEST.types.report ├── dsa │ ├── callgraph │ │ ├── addrtaken_caller.ll │ │ ├── addrtaken_main.ll │ │ ├── calltarget_basic.ll │ │ ├── calltargets_typemismatch.ll │ │ ├── calltargets_typemismatch1.ll │ │ ├── calltargets_variadic.ll │ │ ├── chain.ll │ │ ├── class.ll │ │ ├── decode.ll │ │ ├── dstest_anynotall.ll │ │ ├── externfuncs.ll │ │ ├── fptr.ll │ │ ├── indirect_resolve_chain.ll │ │ ├── inheritance1.ll │ │ ├── inheritance2.ll │ │ ├── inheritance3.ll │ │ ├── lit.local.cfg │ │ ├── loop1.c │ │ ├── loop1.ll │ │ ├── loop2.c │ │ ├── loop2.ll │ │ ├── merge.ll │ │ ├── pr7799.ll │ │ ├── scc.ll │ │ ├── scc1.ll │ │ ├── scc3.c │ │ ├── scc3a.c │ │ ├── scc3b.c │ │ ├── table_dispatch.ll │ │ ├── table_dispatch1.ll │ │ ├── test1.ll │ │ ├── testIncomplete.ll │ │ └── varargs.ll │ ├── equivs │ │ ├── lit.local.cfg │ │ ├── no-callees.ll │ │ └── undef-null-calls.ll │ ├── extern │ │ ├── extern.ll │ │ ├── extern2.ll │ │ ├── extern3.ll │ │ ├── extern_global.ll │ │ ├── extern_global2.c │ │ ├── extern_global2.ll │ │ ├── extern_global_escape.c │ │ ├── extern_global_escape.ll │ │ └── lit.local.cfg │ ├── local │ │ ├── arrayPointers.ll │ │ ├── arrayPointers1.ll │ │ ├── arrayPointers2.ll │ │ ├── arrayPointers3.ll │ │ ├── array_in_struct.ll │ │ ├── array_of_struct.ll │ │ ├── arrays.c │ │ ├── arrays.ll │ │ ├── arrays1.c │ │ ├── arrays1.ll │ │ ├── arrays2.c │ │ ├── arrays2.ll │ │ ├── arrays3.c │ │ ├── arrays3.ll │ │ ├── arrays4.c │ │ ├── arrays4.ll │ │ ├── bitfields1.bc │ │ ├── bitfields1.c │ │ ├── bitfields1.ll │ │ ├── bitfields2.c │ │ ├── bitfields2.ll │ │ ├── bitfields3.c │ │ ├── bitfields3.ll │ │ ├── flags.c │ │ ├── flags.ll │ │ ├── lit.local.cfg │ │ ├── malloc.ll │ │ ├── memcpy.ll │ │ ├── multidimarray.ll │ │ ├── ptr.c │ │ ├── ptr.ll │ │ ├── ptr1.c │ │ ├── ptr1.ll │ │ ├── ptr2.c │ │ ├── ptr2.ll │ │ ├── struct.c │ │ ├── struct.ll │ │ ├── struct1.c │ │ ├── struct1.ll │ │ ├── struct2.ll │ │ ├── struct3.ll │ │ ├── struct4.ll │ │ ├── structFirstField.ll │ │ ├── struct_malloc.ll │ │ ├── union_P21.ll │ │ ├── union_P2I.ll │ │ └── union_P2I_1.ll │ ├── regression │ │ ├── 2010-07-08.FPDeclaration.c │ │ ├── 2010-07-09-vastartUndef.ll │ │ ├── 2010-07-12-SCCLeader.ll │ │ ├── 2010-07-16.CBU_MissingGraph.ll │ │ ├── 2010-07-16.MissingIndirectCallee.ll │ │ ├── 2010-07-16.SimpleLoop.ll │ │ ├── 2010-08-17-VarArgSize.ll │ │ ├── 2010-08-19-SimpleCallGraph.ll │ │ ├── 2010-08-23-InlineCallersSegfault.ll │ │ ├── 2011-03-17-CBUAssert.ll │ │ ├── 2012-04-29.GlobalInitCollapse.ll │ │ ├── 2012-04-29.SQLiteBUInfiniteRecursion.ll │ │ ├── 2012-04-29.StructOOBIndex.ll │ │ ├── 2012-05-05.GlobalCtorsDecl.ll │ │ ├── 2012-05-05.GlobalCtorsSCC.ll │ │ ├── 2012-05-05.PtrToIntInfiniteLoop.ll │ │ ├── 2012-09-25.RCForwarding.ll │ │ ├── 2012-09-27.ConstantAggregate.ll │ │ ├── 2012-11-19.ExternFuncSummaries.ll │ │ ├── 2012-11-19.MultipleVAStartAlias.ll │ │ ├── 2012-11-20.TDUnresolvedIncomplete.ll │ │ ├── 2014-05-06.PR19175-CollapseVA.ll │ │ └── lit.local.cfg │ ├── td │ │ ├── ExternFuncNodeTest1.ll │ │ ├── ExternFuncNodeTest2.ll │ │ ├── ExternFuncNodeTest3.ll │ │ ├── basic-global.ll │ │ ├── call.c │ │ ├── call.ll │ │ ├── call1.c │ │ ├── call1.ll │ │ ├── call2.c │ │ ├── call2.ll │ │ ├── chain.ll │ │ ├── checkIncomplete.ll │ │ ├── checkIncomplete1.ll │ │ ├── fptr.ll │ │ ├── lit.local.cfg │ │ ├── mergeArgs.ll │ │ ├── mergeArgs1.ll │ │ ├── params.c │ │ ├── params.ll │ │ ├── params1.c │ │ ├── params1.ll │ │ ├── recur.c │ │ ├── recur.ll │ │ ├── recur1.c │ │ ├── recur1.ll │ │ ├── recur2.c │ │ ├── recur2.ll │ │ ├── recur3.c │ │ ├── scc-flags.ll │ │ ├── scc-global.ll │ │ ├── testcase.c │ │ └── testcase.ll │ ├── types │ │ ├── array2struct.ll │ │ ├── lit.local.cfg │ │ ├── mrv.ll │ │ ├── mrv1.ll │ │ ├── union.c │ │ ├── union.ll │ │ ├── union1.c │ │ ├── union1.ll │ │ ├── union2.c │ │ ├── union2.ll │ │ ├── union3.c │ │ ├── union3.ll │ │ ├── union4.c │ │ ├── union4.ll │ │ ├── union_arrays.c │ │ └── union_arrays.ll │ └── var_arg │ │ ├── basic.ll │ │ ├── basic_32.ll │ │ ├── basic_64.ll │ │ ├── extern.c │ │ ├── lit.local.cfg │ │ ├── multiple_callee.c │ │ ├── multiple_callee_nomodref.c │ │ ├── print.ll │ │ ├── va_copy_32.ll │ │ └── va_copy_64.ll ├── lit.cfg ├── lit.site.cfg.in ├── pa │ ├── clone │ │ ├── AttrTest.ll │ │ ├── Incomplete.ll │ │ ├── computeNodeMappingFail.ll │ │ └── lit.local.cfg │ └── regression │ │ ├── 2010-07-09-ArgAttrMismatch.ll │ │ ├── 2010-08-17-InvalidIterator.ll │ │ ├── 2010-09-14-Fptr.c │ │ ├── 2010-09-14-Fptr_helper.c │ │ └── lit.local.cfg └── type_checks │ ├── correct │ ├── basic.c │ ├── basic_repeat.c │ ├── libclamav_snprintf.c │ ├── vprintf.c │ └── vprintf1.c │ ├── error │ ├── IntUnion.c │ ├── alloc.c │ ├── indirect_simple.c │ ├── libclamav_snprintf1.c │ ├── misalign.c │ ├── misalign1.c │ └── testEndian.c │ └── regression │ ├── nomain.ll │ └── simple_varargs.ll ├── tools ├── CMakeLists.txt ├── Makefile ├── Pa │ ├── CMakeLists.txt │ ├── Makefile │ └── pa.cpp ├── TypeChecker │ ├── CMakeLists.txt │ ├── Makefile │ └── tc.cpp └── WatchDog │ ├── CMakeLists.txt │ ├── LICENSE.TXT │ ├── Makefile │ └── WatchDog.cpp └── utils ├── NightlyCronTab └── NightlyTest.sh /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include 2 | ${CMAKE_CURRENT_BINARY_DIR}/include) 3 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/poolalloc/Config/config.h.cmake 4 | ${CMAKE_CURRENT_BINARY_DIR}/include/poolalloc/Config/config.h) 5 | add_subdirectory(lib) 6 | add_subdirectory(runtime) 7 | add_subdirectory(tools) 8 | add_subdirectory(test) 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a sample Makefile for a project that uses LLVM. 3 | # 4 | 5 | # 6 | # Indicates our relative path to the top of the project's root directory. 7 | # 8 | LEVEL = . 9 | 10 | # 11 | # Directories that needs to be built. 12 | # 13 | DIRS = lib runtime tools 14 | 15 | # 16 | # Include the Master Makefile that knows how to build all. 17 | # 18 | -include $(LEVEL)/Makefile.common 19 | 20 | notconfigured: 21 | @echo "ERROR: You must configure this project before you can use it!" 22 | @exit 1 23 | 24 | distclean:: clean 25 | ${RM} -f Makefile.common Makefile.config 26 | 27 | -------------------------------------------------------------------------------- /Makefile.common.in: -------------------------------------------------------------------------------- 1 | PROJECT_NAME := poolalloc 2 | PROJ_VERSION := 1.0 3 | 4 | # Set this variable to the top of the LLVM source tree. 5 | LLVM_SRC_ROOT = @LLVM_SRC@ 6 | 7 | # Set this variable to the top level directory where LLVM was built 8 | # (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config). 9 | LLVM_OBJ_ROOT = @LLVM_OBJ@ 10 | 11 | # Set the source root and source directory pathnames 12 | ####PROJ_SRC_DIR := $(subst //,/,@abs_top_srcdir@/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))) 13 | 14 | PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@) 15 | 16 | # Set the root directory of this project's object files 17 | PROJ_OBJ_ROOT := $(subst //,/,@abs_top_objdir@) 18 | 19 | # Set the root directory of this project's install prefix 20 | PROJ_INSTALL_ROOT := @prefix@ 21 | 22 | CXXFLAGS += -Wall -Wno-deprecated 23 | 24 | # 25 | # Paths to various utilities 26 | # 27 | LATEX := @LATEX@ 28 | BIBTEX := @BIBTEX@ 29 | 30 | # Use clang to build bytecode 31 | LLVMCC_OPTION := "clang" 32 | ENABLE_BUILT_CLANG := 1 33 | LLVMCC_EMITIR_FLAG := "-emit-llvm" 34 | 35 | 36 | # Include LLVM's Master Makefile. 37 | include $(LLVM_SRC_ROOT)/Makefile.common 38 | 39 | -------------------------------------------------------------------------------- /ModuleInfo.txt: -------------------------------------------------------------------------------- 1 | # This file defines the relationship of this module to other modules and 2 | # tells llvm-top how to drive it. 3 | 4 | # Declare that this module depends on llvm. 5 | DepModule: llvm 6 | 7 | -------------------------------------------------------------------------------- /Regressions/2006-02-13.ArrayOfObjects.ll: -------------------------------------------------------------------------------- 1 | ; This causes a segfault in pointer compression 2 | ; The pool type is struct.DLL, but the result of malloc is an array of struct.DLL 3 | ; the GEP rewrite assumed that a pointer would have the pool type which isn't true here 4 | 5 | target endian = little 6 | target pointersize = 64 7 | target triple = "alphaev6-unknown-linux-gnu" 8 | deplibs = [ "c", "crtend" ] 9 | %struct.DLL = type { int, %struct.DLL*, %struct.DLL* } 10 | 11 | implementation ; Functions: 12 | 13 | void %main() { 14 | entry: 15 | %tmp.12.i.i = malloc [101 x %struct.DLL] ; <[101 x %struct.DLL]*> [#uses=2] 16 | %tmp.37.i.i = getelementptr [101 x %struct.DLL]* %tmp.12.i.i, int 0, int 0, uint 2 ; <%struct.DLL**> [#uses=1] 17 | %tmp.42.i.i = getelementptr [101 x %struct.DLL]* %tmp.12.i.i, int 0, int 0 ; <%struct.DLL*> [#uses=1] 18 | store %struct.DLL* %tmp.42.i.i, %struct.DLL** %tmp.37.i.i 19 | unreachable 20 | } 21 | -------------------------------------------------------------------------------- /Regressions/2006-02-23.memcpy.ll: -------------------------------------------------------------------------------- 1 | ; pointer compression tries to turn the llvm.memcpy into llvm.memcpy_pc 2 | ; this is of course bad. It should materialize the pointers. 3 | target endian = little 4 | target pointersize = 64 5 | target triple = "alphaev6-unknown-linux-gnu" 6 | deplibs = [ "c", "crtend" ] 7 | %struct.spec_fd_t = type { int, int, int, ubyte* } 8 | %spec_fd = external global [3 x %struct.spec_fd_t] ; <[3 x %struct.spec_fd_t]*> [#uses=2] 9 | 10 | implementation ; Functions: 11 | 12 | declare void %llvm.memcpy(sbyte*, sbyte*, ulong, uint) 13 | 14 | void %main() { 15 | entry: 16 | br bool false, label %no_exit.0.i161, label %endif.0 17 | 18 | endif.0: ; preds = %entry 19 | ret void 20 | 21 | no_exit.0.i161: ; preds = %entry 22 | %tmp.25.i = getelementptr [3 x %struct.spec_fd_t]* %spec_fd, long 0, int 0, uint 3 ; [#uses=1] 23 | %tmp.26.i = malloc ubyte, uint 0 ; [#uses=1] 24 | store ubyte* %tmp.26.i, ubyte** %tmp.25.i 25 | br bool false, label %no_exit.1.i, label %then.4 26 | 27 | no_exit.1.i: ; preds = %no_exit.0.i161 28 | %tmp.103.i = load ubyte** getelementptr ([3 x %struct.spec_fd_t]* %spec_fd, long 0, int 0, uint 3) ; [#uses=1] 29 | %tmp.118.i = cast ubyte* %tmp.103.i to sbyte* ; [#uses=1] 30 | tail call void %llvm.memcpy( sbyte* null, sbyte* %tmp.118.i, ulong 0, uint 1 ) 31 | ret void 32 | 33 | then.4: ; preds = %no_exit.0.i161 34 | ret void 35 | } 36 | -------------------------------------------------------------------------------- /Regressions/2006-04-13.MixedAllocaGlobals.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 2 | target endian = little 3 | target pointersize = 32 4 | target triple = "i686-pc-linux-gnu" 5 | deplibs = [ "c", "crtend" ] 6 | %struct.MT = type { int, [100 x [3 x [3 x int]]], [3 x [3 x int]], [3 x [3 x int]] } 7 | %struct._IO_FILE = type { int, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, sbyte*, %struct._IO_marker*, %struct._IO_FILE*, int, int, int, ushort, sbyte, [1 x sbyte], sbyte*, long, sbyte*, sbyte*, int, [52 x sbyte] } 8 | %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, int } 9 | %struct.cellbox = type { sbyte*, sbyte, sbyte, int, int, short, short, short, short, short, short, short, %struct.tilebox* } 10 | %struct.netbox = type { %struct.netbox*, int, int, int, int, int, int, short, short, short, sbyte, sbyte, sbyte, sbyte } 11 | %struct.termbox = type { %struct.termbox*, %struct.netbox*, int, int, short, [2 x short], [2 x short], short } 12 | %struct.tilebox = type { short, short, short, short, %struct.termbox* } 13 | %carray = external global %struct.cellbox** ; <%struct.cellbox***> [#uses=1] 14 | %foo = external global sbyte* 15 | 16 | implementation ; Functions: 17 | 18 | void %main() { 19 | entry: 20 | call fastcc void %readcell( ) 21 | ret void 22 | } 23 | 24 | ;fastcc sbyte* %safe_malloc(uint %size) { 25 | ;entry: 26 | ; %tmp.0 = malloc sbyte, uint %size ; [#uses=1] 27 | ; ret sbyte* %tmp.0 28 | ;} 29 | 30 | fastcc void %readcell() { 31 | entry: 32 | %input = alloca [1024 x sbyte] ; <[1024 x sbyte]*> [#uses=1] 33 | %tmp.48384 = getelementptr [1024 x sbyte]* %input, int 0, int 0 ; [#uses=1] 34 | ; %tmp.7314 = call fastcc sbyte* %safe_malloc( uint 0 ) ; [#uses=2] 35 | %tmp.7314 = malloc sbyte, uint 0 36 | store sbyte* %tmp.7314, sbyte** %foo 37 | call void %llvm.memcpy.i32( sbyte* %tmp.7314, sbyte* %tmp.48384, uint 0, uint 1 ) 38 | ret void 39 | } 40 | 41 | declare void %llvm.memcpy.i32(sbyte*, sbyte*, uint, uint) 42 | -------------------------------------------------------------------------------- /Regressions/2008-09-29.calls.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct OP { 4 | void (*func)(struct OP*); 5 | }; 6 | 7 | void bar(struct OP *op); 8 | 9 | void foo(struct OP *op) { 10 | printf("Foo\n"); 11 | op->func = bar; 12 | } 13 | 14 | void bar(struct OP *op) { 15 | printf("Bar\n"); 16 | op->func = foo; 17 | } 18 | 19 | int main(int argc, char **argv) { 20 | int i; 21 | struct OP op; 22 | op.func = foo; 23 | for(i = 0; i < 10; ++i) { 24 | op.func(&op); 25 | } 26 | return 0; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Regressions/2009-08-05.packed.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'foo.o' 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | %struct.pa = type <{ i8, i32*, i8 }> 5 | @.str = private constant [25 x i8] c"Hello World %d %d %s %s\0A\00", align 1 ; <[25 x i8]*> [#uses=1] 6 | @.str1 = private constant [22 x i8] c"Hello World %d %d %s\0A\00", align 1 ; <[22 x i8]*> [#uses=1] 7 | 8 | define void @foo(i32* nocapture %y) nounwind noinline { 9 | entry: 10 | store i32 3, i32* %y, align 4 11 | ret void 12 | } 13 | 14 | define void @bar(%struct.pa* nocapture %S, i32* %v) nounwind { 15 | entry: 16 | %0 = getelementptr %struct.pa* %S, i64 0, i32 0 ; [#uses=1] 17 | store i8 0, i8* %0, align 1 18 | %1 = getelementptr %struct.pa* %S, i64 0, i32 1 ; [#uses=1] 19 | store i32* %v, i32** %1, align 1 20 | %2 = getelementptr %struct.pa* %S, i64 0, i32 2 ; [#uses=1] 21 | store i8 0, i8* %2, align 1 22 | ret void 23 | } 24 | 25 | define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { 26 | entry: 27 | %0 = malloc i32 ; [#uses=2] 28 | store i32 %argc, i32* %0, align 8 29 | tail call void @foo(i32* %0) nounwind noinline 30 | %1 = getelementptr i8** %argv, i64 1 ; [#uses=1] 31 | %2 = load i8** %1, align 8 ; [#uses=1] 32 | %3 = tail call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([25 x i8]* @.str, i64 0, i64 0), i32 %argc, i32 2, i8* %2) nounwind ; [#uses=0] 33 | %4 = load i8** %argv, align 8 ; [#uses=1] 34 | %5 = tail call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([22 x i8]* @.str1, i64 0, i64 0), i32 %argc, i32 2, i8* %4) nounwind ; [#uses=0] 35 | ret i32 %argc 36 | } 37 | 38 | declare i32 @printf(i8* nocapture, ...) nounwind 39 | -------------------------------------------------------------------------------- /autoconf/AutoRegen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | die () { 3 | echo "$@" 1>&2 4 | exit 1 5 | } 6 | test -d autoconf && test -f autoconf/configure.ac && cd autoconf 7 | test -f configure.ac || die "Can't find 'autoconf' dir; please cd into it first" 8 | autoconf --version | egrep '2\.5[0-9]' > /dev/null 9 | if test $? -ne 0 ; then 10 | die "Your autoconf was not detected as being 2.5x" 11 | fi 12 | cwd=`pwd` 13 | if test -d ../../../autoconf/m4 ; then 14 | cd ../../../autoconf/m4 15 | llvm_m4=`pwd` 16 | llvm_src_root='`(cd ../..; pwd)`' 17 | llvm_obj_root='`(cd ../..; pwd)`' 18 | cd $cwd 19 | elif test -d ../../llvm/autoconf/m4 ; then 20 | cd ../../llvm/autoconf/m4 21 | llvm_m4=`pwd` 22 | llvm_src_root='`(cd ../..; pwd)`' 23 | llvm_obj_root='`(cd ../..; pwd)`' 24 | cd $cwd 25 | else 26 | while true ; do 27 | echo "LLVM source root not found." 28 | read -p "Enter full path to LLVM source:" 29 | if test -d "$REPLY/autoconf/m4" ; then 30 | llvm_src_root="$REPLY" 31 | llvm_m4="$REPLY/autoconf/m4" 32 | read -p "Enter full path to LLVM objects (empty for same as source):" 33 | if test -d "$REPLY" ; then 34 | llvm_obj_root="$REPLY" 35 | else 36 | llvm_obj_root="$llvm_src_root" 37 | fi 38 | break 39 | fi 40 | done 41 | fi 42 | # Patch the LLVM_ROOT in configure.ac, if it needs it 43 | cp configure.ac configure.bak 44 | #sed -e "s#^LLVM_SRC_ROOT=.*#LLVM_SRC_ROOT=\"$llvm_src_root\"#" \ 45 | # -e "s#^LLVM_OBJ_ROOT=.*#LLVM_OBJ_ROOT=\"$llvm_obj_root\"#" configure.bak > configure.ac 46 | echo "Regenerating aclocal.m4 with aclocal" 47 | rm -f aclocal.m4 48 | aclocal -I $llvm_m4 -I "$llvm_m4/.." || die "aclocal failed" 49 | echo "Regenerating configure with autoconf 2.5x" 50 | autoconf --warnings=all -o ../configure configure.ac || die "autoconf failed" 51 | cd .. 52 | exit 0 53 | -------------------------------------------------------------------------------- /autoconf/mkinstalldirs: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # mkinstalldirs --- make directory hierarchy 3 | # Author: Noah Friedman 4 | # Created: 1993-05-16 5 | # Public domain 6 | 7 | # $Id$ 8 | 9 | errstatus=0 10 | dirmode="" 11 | 12 | usage="\ 13 | Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." 14 | 15 | # process command line arguments 16 | while test $# -gt 0 ; do 17 | case "${1}" in 18 | -h | --help | --h* ) # -h for help 19 | echo "${usage}" 1>&2; exit 0 ;; 20 | -m ) # -m PERM arg 21 | shift 22 | test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; } 23 | dirmode="${1}" 24 | shift ;; 25 | -- ) shift; break ;; # stop option processing 26 | -* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option 27 | * ) break ;; # first non-opt arg 28 | esac 29 | done 30 | 31 | for file 32 | do 33 | if test -d "$file"; then 34 | shift 35 | else 36 | break 37 | fi 38 | done 39 | 40 | case $# in 41 | 0) exit 0 ;; 42 | esac 43 | 44 | case $dirmode in 45 | '') 46 | if mkdir -p -- . 2>/dev/null; then 47 | echo "mkdir -p -- $*" 48 | exec mkdir -p -- "$@" 49 | fi ;; 50 | *) 51 | if mkdir -m "$dirmode" -p -- . 2>/dev/null; then 52 | echo "mkdir -m $dirmode -p -- $*" 53 | exec mkdir -m "$dirmode" -p -- "$@" 54 | fi ;; 55 | esac 56 | 57 | for file 58 | do 59 | set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` 60 | shift 61 | 62 | pathcomp= 63 | for d 64 | do 65 | pathcomp="$pathcomp$d" 66 | case "$pathcomp" in 67 | -* ) pathcomp=./$pathcomp ;; 68 | esac 69 | 70 | if test ! -d "$pathcomp"; then 71 | echo "mkdir $pathcomp" 72 | 73 | mkdir "$pathcomp" || lasterr=$? 74 | 75 | if test ! -d "$pathcomp"; then 76 | errstatus=$lasterr 77 | else 78 | if test ! -z "$dirmode"; then 79 | echo "chmod $dirmode $pathcomp" 80 | 81 | lasterr="" 82 | chmod "$dirmode" "$pathcomp" || lasterr=$? 83 | 84 | if test ! -z "$lasterr"; then 85 | errstatus=$lasterr 86 | fi 87 | fi 88 | fi 89 | fi 90 | 91 | pathcomp="$pathcomp/" 92 | done 93 | done 94 | 95 | exit $errstatus 96 | 97 | # Local Variables: 98 | # mode: shell-script 99 | # sh-indentation: 3 100 | # End: 101 | # mkinstalldirs ends here 102 | -------------------------------------------------------------------------------- /docs/dsa-manual/Makefile: -------------------------------------------------------------------------------- 1 | LATEX=latex 2 | 3 | all: manual.pdf 4 | 5 | %.pdf: %.ps 6 | ps2pdf $< 7 | 8 | %.ps: %.dvi 9 | dvips -o $@ $< -t letter 10 | 11 | %.dvi: %.tex 12 | -rm -f *.aux 13 | $(LATEX) $< 14 | 15 | clean: 16 | rm -f *.aux *.log *.pdf *.ps *.dvi 17 | 18 | -------------------------------------------------------------------------------- /include/LinkDSA.h: -------------------------------------------------------------------------------- 1 | namespace { 2 | struct ForceDSALinking { 3 | ForceDSALinking() { 4 | // We must reference the passes in such a way that compilers will not 5 | // delete it all as dead code, even with whole program optimization, 6 | // yet is effectively a NO-OP. As the compiler isn't smart enough 7 | // to know that getenv() never returns -1, this will do the job. 8 | if (std::getenv("bar") != (char*) -1) 9 | return; 10 | 11 | (void)new EntryPointAnalysis(); 12 | (void)new llvm::BasicDataStructures(); 13 | (void)new llvm::LocalDataStructures(); 14 | (void)new llvm::StdLibDataStructures(); 15 | (void)new llvm::BUDataStructures(); 16 | (void)new llvm::CompleteBUDataStructures(); 17 | (void)new llvm::EquivBUDataStructures(); 18 | (void)new llvm::TDDataStructures(); 19 | (void)new llvm::EQTDDataStructures(); 20 | (void)new llvm::RTAssociate(); 21 | } 22 | } ForceDSALinking; // Force link by creating a global definition. 23 | } 24 | -------------------------------------------------------------------------------- /include/LinkPA.h: -------------------------------------------------------------------------------- 1 | namespace { 2 | struct ForcePALinking { 3 | ForcePALinking() { 4 | // We must reference the passes in such a way that compilers will not 5 | // delete it all as dead code, even with whole program optimization, 6 | // yet is effectively a NO-OP. As the compiler isn't smart enough 7 | // to know that getenv() never returns -1, this will do the job. 8 | if (std::getenv("bar") != (char*) -1) 9 | return; 10 | 11 | (void)new EntryPointAnalysis(); 12 | (void)new llvm::PoolAllocate(); 13 | (void)new llvm::PoolAllocateGroup(); 14 | } 15 | } ForcePALinking; // Force link by creating a global definition. 16 | } 17 | -------------------------------------------------------------------------------- /include/assistDS/ArgCast.h: -------------------------------------------------------------------------------- 1 | //===-------- ArgCast.cpp - Cast Arguments to Calls -----------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // Convert 10 | // call(bitcast (.., T1 arg, ...)F to(..., T2 arg, ...))(..., T2 val, ...) 11 | // to 12 | // val1 = bitcast T2 val to T1 13 | // call F (..., T1 val1, ...) 14 | //===----------------------------------------------------------------------===// 15 | 16 | #include "llvm/IR/Instructions.h" 17 | #include "llvm/IR/Constants.h" 18 | #include "llvm/IR/Module.h" 19 | #include "llvm/Pass.h" 20 | 21 | namespace llvm { 22 | // 23 | // Class: ArgCast 24 | // 25 | // Description: 26 | // Implement an LLVM pass that cleans up call sites that take casted args 27 | // 28 | class ArgCast : public ModulePass { 29 | public: 30 | static char ID; 31 | ArgCast() : ModulePass(ID) {} 32 | virtual bool runOnModule(Module& M); 33 | }; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /include/assistDS/DSNodeEquivs.h: -------------------------------------------------------------------------------- 1 | //===- DSNodeEquivs.h - Build DSNode equivalence classes ------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This pass computes equivalence classes of DSNodes across DSGraphs. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef DSNODEEQUIVS_H 15 | #define DSNODEEQUIVS_H 16 | 17 | #include "dsa/DataStructure.h" 18 | #include "dsa/DSGraph.h" 19 | #include "dsa/DSNode.h" 20 | 21 | #include "llvm/ADT/EquivalenceClasses.h" 22 | 23 | #include 24 | 25 | namespace llvm { 26 | 27 | typedef std::vector FunctionList; 28 | typedef FunctionList::iterator FunctionList_it; 29 | 30 | class DSNodeEquivs : public ModulePass { 31 | private: 32 | EquivalenceClasses Classes; 33 | 34 | void buildDSNodeEquivs(Module &M); 35 | 36 | void addNodesFromGraph(DSGraph *G); 37 | FunctionList getCallees(CallSite &CS); 38 | void equivNodesThroughCallsite(CallInst *CI); 39 | void equivNodesToGlobals(DSGraph *G); 40 | void equivNodeMapping(DSGraph::NodeMapTy & NM); 41 | 42 | public: 43 | static char ID; 44 | 45 | DSNodeEquivs() : ModulePass(ID) {} 46 | 47 | void getAnalysisUsage(AnalysisUsage &AU) const { 48 | AU.addRequiredTransitive(); 49 | AU.setPreservesAll(); 50 | } 51 | 52 | bool runOnModule(Module &M); 53 | 54 | // Returns the computed equivalence classes. Two DSNodes in the same 55 | // equivalence class may alias. DSNodes may also alias if they have the 56 | // Incomplete, Unknown, or External flags set (even if they are in different 57 | // equivalence classes). 58 | const EquivalenceClasses &getEquivalenceClasses(); 59 | 60 | // Returns a DSNode for the specified value. Note that two nodes may alias 61 | // even if they have different DSNodes (because the DSNodes may belong to 62 | // different DSGraphs). 63 | const DSNode *getMemberForValue(const Value *V); 64 | }; 65 | 66 | } 67 | 68 | #endif // DSNODEEQUIVS_H 69 | -------------------------------------------------------------------------------- /include/assistDS/FuncSimplify.h: -------------------------------------------------------------------------------- 1 | //===-------- ArgCast.cpp - Cast Arguments to Calls -----------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | //===----------------------------------------------------------------------===// 10 | 11 | #include "llvm/IR/Instructions.h" 12 | #include "llvm/IR/Module.h" 13 | #include "llvm/Pass.h" 14 | 15 | namespace llvm { 16 | // 17 | // Class: FuncSimplify 18 | // 19 | // Description: 20 | // Replace all internal aliases with the 21 | // aliasee value 22 | // 23 | class FuncSimplify : public ModulePass { 24 | public: 25 | static char ID; 26 | FuncSimplify() : ModulePass(ID) {} 27 | virtual bool runOnModule(Module& M); 28 | }; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /include/assistDS/FuncSpec.h: -------------------------------------------------------------------------------- 1 | //===-- FuncSpec.cpp - Clone Functions With Constant Function Ptr Args ----===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This pass clones functions that take constant function pointers as arguments 11 | // from some call sites. It changes those call sites to call cloned functions. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "llvm/IR/Instructions.h" 16 | #include "llvm/IR/Module.h" 17 | #include "llvm/Pass.h" 18 | 19 | namespace llvm { 20 | // 21 | // Class: FuncSpec 22 | // 23 | // Description: 24 | // Implement an LLVM pass that clones functions which are passed 25 | // as an argument 26 | // 27 | // 28 | class FuncSpec : public ModulePass { 29 | public: 30 | static char ID; 31 | FuncSpec() : ModulePass(ID) {} 32 | virtual bool runOnModule(Module& M); 33 | }; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /include/assistDS/GEPExprArgs.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Identify GEPs used as arguments to call sites. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "llvm/IR/Instructions.h" 15 | #include "llvm/IR/Module.h" 16 | #include "llvm/Pass.h" 17 | 18 | namespace llvm { 19 | // 20 | // Class: GEPExprArgs 21 | // 22 | // Description: 23 | // Implement an LLVM pass that clones functions which are passed GEPs 24 | // as an argument 25 | // 26 | // 27 | class GEPExprArgs : public ModulePass { 28 | public: 29 | static char ID; 30 | GEPExprArgs() : ModulePass(ID) {} 31 | virtual bool runOnModule(Module& M); 32 | }; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /include/assistDS/IndCloner.h: -------------------------------------------------------------------------------- 1 | //===-- IndCloner.h - Clone Indirectly Called Functions -------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This code defines a pass which clones functions which could potentially be 11 | // used in indirect function calls. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "llvm/IR/Instructions.h" 16 | #include "llvm/IR/Module.h" 17 | #include "llvm/Pass.h" 18 | 19 | namespace llvm { 20 | // 21 | // Class: IndClone 22 | // 23 | // Description: 24 | // Implement an LLVM pass that clones functions which could be used for 25 | // indirect function calls. 26 | // 27 | class IndClone : public ModulePass { 28 | public: 29 | static char ID; 30 | IndClone() : ModulePass(ID) {} 31 | virtual bool runOnModule(Module& M); 32 | }; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /include/assistDS/Int2PtrCmp.h: -------------------------------------------------------------------------------- 1 | //===-- Int2PtrCmp.cpp - Merge inttoptr/ptrtoint --------------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Remove unnecessary inttoptr casts 11 | // Specially ones used in just compares 12 | // Most cases derived from InstCombine 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #include "llvm/IR/Instructions.h" 17 | #include "llvm/IR/Module.h" 18 | #include "llvm/Pass.h" 19 | 20 | 21 | namespace llvm { 22 | // 23 | // Class: Int2PtrCmp 24 | // 25 | // 26 | class Int2PtrCmp : public ModulePass { 27 | public: 28 | static char ID; 29 | Int2PtrCmp() : ModulePass(ID) {} 30 | virtual bool runOnModule(Module& M); 31 | }; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /include/assistDS/LoadArgs.h: -------------------------------------------------------------------------------- 1 | //===-- LoadArgs.cpp - Promote args if they came from loads ---------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Identify calls, that are passed arguemtns that are LoadInsts. 11 | // Pass the original pointer instead. Helps improve some 12 | // context sensitivity. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #include "llvm/IR/Instructions.h" 17 | #include "llvm/IR/Module.h" 18 | #include "llvm/Pass.h" 19 | 20 | namespace llvm { 21 | // 22 | // Class: LoadArgs 23 | // 24 | // Description: 25 | // Implement an LLVM pass that clones functions which are passed loads 26 | // as an argument 27 | // 28 | // 29 | class LoadArgs : public ModulePass { 30 | public: 31 | static char ID; 32 | LoadArgs() : ModulePass(ID) {} 33 | virtual bool runOnModule(Module& M); 34 | }; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /include/assistDS/MergeGEP.h: -------------------------------------------------------------------------------- 1 | //===-- MergeGEP.cpp - Merge GEPs for indexing in arrays ------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Merge chained GEPs; Specially useful for arrays inside structs 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "llvm/IR/Instructions.h" 15 | #include "llvm/IR/Module.h" 16 | #include "llvm/Pass.h" 17 | 18 | namespace llvm { 19 | // 20 | // Class: MergeArrayGEP 21 | // 22 | class MergeArrayGEP : public ModulePass { 23 | public: 24 | static char ID; 25 | MergeArrayGEP() : ModulePass(ID) {} 26 | virtual bool runOnModule(Module& M); 27 | }; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /include/assistDS/SimplifyExtractValue.h: -------------------------------------------------------------------------------- 1 | //===-- SimplifyExtractValue.cpp - Remove extraneous extractvalue insts----===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Simplify extractvalue 11 | // 12 | // Derived from InstCombine 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #include "llvm/IR/Instructions.h" 17 | #include "llvm/IR/Module.h" 18 | #include "llvm/Pass.h" 19 | 20 | namespace llvm { 21 | // 22 | // Class: SimplifyEV 23 | // 24 | class SimplifyEV : public ModulePass { 25 | public: 26 | static char ID; 27 | SimplifyEV() : ModulePass(ID) {} 28 | virtual bool runOnModule(Module& M); 29 | }; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /include/assistDS/SimplifyGEP.h: -------------------------------------------------------------------------------- 1 | //===--------------- SimplifyGEP.cpp - Simplify GEPs types ---------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Simplify GEPs with bitcasts (mostly cloned from InstCombine) 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "llvm/IR/Instructions.h" 15 | #include "llvm/IR/Module.h" 16 | #include "llvm/Pass.h" 17 | 18 | namespace llvm { 19 | // 20 | // Class: SimplifyGEP 21 | // 22 | class SimplifyGEP : public ModulePass { 23 | public: 24 | static char ID; 25 | SimplifyGEP() : ModulePass(ID) {} 26 | virtual bool runOnModule(Module& M); 27 | }; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /include/assistDS/SimplifyInsertValue.h: -------------------------------------------------------------------------------- 1 | //===-- SimplifyInsertValue.cpp - Remove extraneous insertvalue insts------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Simplify insertvalue 11 | // Replace insertvalue by storess where possible 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "llvm/IR/Instructions.h" 16 | #include "llvm/IR/Module.h" 17 | #include "llvm/Pass.h" 18 | 19 | namespace llvm { 20 | // 21 | // Class: SimplifyIV 22 | // 23 | class SimplifyIV : public ModulePass { 24 | public: 25 | static char ID; 26 | SimplifyIV() : ModulePass(ID) {} 27 | virtual bool runOnModule(Module& M); 28 | }; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /include/assistDS/SimplifyLoad.h: -------------------------------------------------------------------------------- 1 | //===--------------- SimplifyLoad.cpp - Simplify load insts ---------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Derived from InstCombine 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "llvm/IR/Instructions.h" 15 | #include "llvm/IR/Module.h" 16 | #include "llvm/Pass.h" 17 | 18 | namespace llvm { 19 | // 20 | // Class: SimplifyLoad 21 | // 22 | class SimplifyLoad : public ModulePass { 23 | public: 24 | static char ID; 25 | SimplifyLoad() : ModulePass(ID) {} 26 | virtual bool runOnModule(Module& M); 27 | }; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /include/assistDS/StructReturnToPointer.h: -------------------------------------------------------------------------------- 1 | //===-------- StructReturnToPointer.cpp ------------------------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // For functions that return structures, 11 | // transform them to return a pointer to the structure instead. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "llvm/IR/Instructions.h" 16 | #include "llvm/IR/Module.h" 17 | #include "llvm/Pass.h" 18 | 19 | namespace llvm { 20 | // 21 | // Class: StructRet 22 | // 23 | class StructRet : public ModulePass { 24 | public: 25 | static char ID; 26 | StructRet() : ModulePass(ID) {} 27 | virtual bool runOnModule(Module& M); 28 | }; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /include/assistDS/TypeChecksOpt.h: -------------------------------------------------------------------------------- 1 | //===---------- TypeChecksOpt.h - Remove safe runtime type checks ---------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This pass removes type checks that are statically proven safe 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef TYPE_CHECKS_OPT_H 15 | #define TYPE_CHECKS_OPT_H 16 | 17 | #include "dsa/TypeSafety.h" 18 | 19 | #include "llvm/Pass.h" 20 | #include "llvm/IR/Instructions.h" 21 | #include "llvm/IR/CallSite.h" 22 | 23 | #include 24 | 25 | namespace llvm { 26 | 27 | class Type; 28 | class Value; 29 | 30 | class TypeChecksOpt : public ModulePass { 31 | 32 | private: 33 | 34 | // Analysis from other passes. 35 | dsa::TypeSafety *TS; 36 | std::list toDelete; 37 | 38 | public: 39 | static char ID; 40 | TypeChecksOpt() : ModulePass(ID) {} 41 | virtual bool runOnModule(Module &M); 42 | 43 | virtual void getAnalysisUsage(AnalysisUsage &AU) const { 44 | AU.addRequired >(); 45 | } 46 | 47 | }; 48 | 49 | } // End llvm namespace 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/dsa/AddressTakenAnalysis.h: -------------------------------------------------------------------------------- 1 | //===-- AddressTakenAnalysis.h - Identify address Taken Values-------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This pass helps find which functions are address taken in a module. 11 | // Functions are considered to be address taken if they are either stored, 12 | // or passed as arguments to functions. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #ifndef _ADDRESSTAKENANALYSIS_H 17 | #define _ADDRESSTAKENANALYSIS_H 18 | 19 | #include "llvm/Pass.h" 20 | 21 | #include 22 | #include 23 | 24 | namespace llvm { 25 | class Function; 26 | class Module; 27 | class Instruction; 28 | 29 | class AddressTakenAnalysis : public llvm::ModulePass { 30 | std::set addressTakenFunctions; 31 | public: 32 | static char ID; 33 | AddressTakenAnalysis() : ModulePass (ID) {} 34 | virtual ~AddressTakenAnalysis(); 35 | 36 | bool runOnModule(llvm::Module&); 37 | 38 | virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; 39 | 40 | bool hasAddressTaken(llvm::Function *); 41 | 42 | }; 43 | 44 | } 45 | 46 | #endif /* _ADDRESSTAKENANALYSIS_H */ 47 | 48 | -------------------------------------------------------------------------------- /include/dsa/AllocatorIdentification.h: -------------------------------------------------------------------------------- 1 | //===-- AllocatorIdentification.h - Identify alloc wrappers --------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // Identify malloc/free wrappers. 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef _ALLOCATORIDENTIFICATION_H 13 | #define _ALLOCATORIDENTIFICATION_H 14 | 15 | #include 16 | #include "llvm/Pass.h" 17 | #include "llvm/IR/Value.h" 18 | 19 | namespace llvm { 20 | class Function; 21 | class Module; 22 | class Instruction; 23 | 24 | class AllocIdentify : public llvm::ModulePass { 25 | protected: 26 | std::set allocators; 27 | std::set deallocators; 28 | bool flowsFrom(Value *Dest,Value *Src); 29 | 30 | public: 31 | std::set::iterator alloc_begin() { 32 | return allocators.begin(); 33 | } 34 | std::set::iterator alloc_end() { 35 | return allocators.end(); 36 | } 37 | std::set::iterator dealloc_begin() { 38 | return deallocators.begin(); 39 | } 40 | std::set::iterator dealloc_end() { 41 | return deallocators.end(); 42 | } 43 | static char ID; 44 | AllocIdentify(); 45 | virtual ~AllocIdentify(); 46 | bool runOnModule(llvm::Module&); 47 | virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; 48 | virtual const char * getPassName() const { 49 | return "Allocator Identification Analysis (find malloc/free wrappers)"; 50 | } 51 | }; 52 | 53 | } 54 | 55 | #endif /* _ALLOCATORIDENTIFICATION_H */ 56 | 57 | -------------------------------------------------------------------------------- /include/dsa/CallTargets.h: -------------------------------------------------------------------------------- 1 | //=- llvm/Analysis/CallTargets.h - Resolve Indirect Call Targets --*- C++ -*-=// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This pass uses DSA to map targets of all calls, and reports on if it 11 | // thinks it knows all targets of a given call. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef LLVM_ANALYSIS_CALLTARGETS_H 16 | #define LLVM_ANALYSIS_CALLTARGETS_H 17 | 18 | #include "llvm/Pass.h" 19 | #include "llvm/IR/CallSite.h" 20 | #include "dsa/DataStructure.h" 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | using namespace llvm; 27 | namespace dsa{ 28 | 29 | template 30 | class CallTargetFinder : public ModulePass { 31 | std::map > IndMap; 32 | std::set CompleteSites; 33 | std::list AllSites; 34 | 35 | void findIndTargets(Module &M); 36 | public: 37 | static char ID; 38 | CallTargetFinder() : ModulePass(ID) {} 39 | 40 | virtual bool runOnModule(Module &M); 41 | 42 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 43 | 44 | virtual void print(llvm::raw_ostream &O, const Module *M) const; 45 | 46 | // Given a CallSite, get an iterator of callees 47 | std::vector::iterator begin(CallSite cs){ 48 | return IndMap[cs].begin(); 49 | } 50 | std::vector::iterator end(CallSite cs){ 51 | return IndMap[cs].end(); 52 | } 53 | unsigned size(CallSite cs){ 54 | return IndMap[cs].size(); 55 | } 56 | 57 | // Iterate over CallSites in program 58 | std::list::iterator cs_begin(){ 59 | return AllSites.begin(); 60 | } 61 | std::list::iterator cs_end(){ 62 | return AllSites.end(); 63 | } 64 | 65 | // Do we think we have complete knowledge of this site? 66 | // That is, do we think there are no missing callees 67 | bool isComplete(CallSite cs) const { 68 | return CompleteSites.find(cs) != CompleteSites.end(); 69 | } 70 | }; 71 | 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /include/dsa/EntryPointAnalysis.h: -------------------------------------------------------------------------------- 1 | //===-- EntryPointAnalysis.h - Entry point Finding Pass -------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This is a general way of finding entry points in a system. Simple programs 11 | // will use the main version. Libraries and OS kernels can have more 12 | // specialized versions. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #ifndef _ENTRYPOINTANALYSIS_H 17 | #define _ENTRYPOINTANALYSIS_H 18 | 19 | namespace llvm { 20 | class Function; 21 | class Module; 22 | } 23 | 24 | #include 25 | #include "llvm/Pass.h" 26 | 27 | class EntryPointAnalysis : public llvm::ModulePass { 28 | std::set names; 29 | bool haveNames; 30 | public: 31 | static char ID; 32 | EntryPointAnalysis(); 33 | virtual ~EntryPointAnalysis(); 34 | 35 | /// print - Print out the analysis results... 36 | /// 37 | void print(llvm::raw_ostream &O, const llvm::Module *M) const; 38 | 39 | bool runOnModule(llvm::Module&); 40 | 41 | virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const; 42 | 43 | bool isEntryPoint(const llvm::Function* F) const; 44 | 45 | void findEntryPoints(const llvm::Module& M, 46 | std::vector& dest) const; 47 | 48 | }; 49 | 50 | 51 | 52 | #endif /* _ENTRYPOINTANALYSIS_H */ 53 | 54 | -------------------------------------------------------------------------------- /include/dsa/stl_util.h: -------------------------------------------------------------------------------- 1 | #ifndef _DSA_STL_UTIL_H_ 2 | #define _DSA_STL_UTIL_H_ 3 | 4 | #include "llvm/ADT/ilist.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace llvm { 10 | 11 | // Splicing one container into another as efficiently as we can 12 | template 13 | inline void splice(std::list& Dst, std::list& Src) { 14 | Dst.splice(Dst.end(), Src); 15 | } 16 | template 17 | inline void splice(ilist& Dst, ilist& Src) { 18 | Dst.splice(Dst.end(), Src); 19 | } 20 | 21 | template 22 | static void splice(std::vector& Dst, std::vector& Src) { 23 | if (Dst.empty()) 24 | Dst.swap(Src); 25 | else { 26 | Dst.insert(Dst.end(), Src.begin(), Src.end()); 27 | Src.clear(); 28 | } 29 | } 30 | 31 | template 32 | inline void splice(std::map& Dst, std::map& Src) { 33 | if (Dst.empty()) 34 | Dst.swap(Src); 35 | else { 36 | Dst.insert(Src.begin(), Src.end()); 37 | Src.clear(); 38 | } 39 | } 40 | 41 | // Efficient sort 42 | template 43 | inline void sort(std::vector& L) { 44 | std::sort(L.begin(), L.end()); 45 | } 46 | 47 | template 48 | inline void sort(std::list& L) { 49 | L.sort(); 50 | } 51 | 52 | } // end namespace llvm 53 | #endif // _DSA_STL_UTIL_H_ 54 | 55 | -------------------------------------------------------------------------------- /include/dsa/super_set.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: super_set.h 3 | * Author: andrew 4 | * 5 | * Created on March 10, 2010, 2:04 PM 6 | */ 7 | 8 | #ifndef _SUPER_SET_H 9 | #define _SUPER_SET_H 10 | 11 | #include "dsa/svset.h" 12 | #include 13 | 14 | // Contains stable references to a set 15 | // The sets can be grown. 16 | 17 | template 18 | class SuperSet { 19 | //std::set provides stable iterators, and that matters a lot 20 | typedef svset InnerSetTy; 21 | typedef std::set OuterSetTy; 22 | OuterSetTy container; 23 | public: 24 | typedef const typename OuterSetTy::value_type* setPtr; 25 | 26 | setPtr getOrCreate(svset& S) { 27 | if (S.empty()) return 0; 28 | return &(*container.insert(S).first); 29 | } 30 | 31 | setPtr getOrCreate(setPtr P, Ty t) { 32 | svset s; 33 | if (P) 34 | s.insert(P->begin(), P->end()); 35 | s.insert(t); 36 | return getOrCreate(s); 37 | } 38 | }; 39 | 40 | 41 | 42 | #endif /* _SUPER_SET_H */ 43 | 44 | -------------------------------------------------------------------------------- /include/poolalloc/MMAPSupport.h: -------------------------------------------------------------------------------- 1 | //===- MMAPSupport.h - mmap portability wrappers ----------------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file allows clients to use some functionality of mmap efficiently and 11 | // portably. This is used for the pool allocator runtime implementations. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "poolalloc/Config/config.h" 16 | #include 17 | #include 18 | 19 | #ifdef HAVE_FCNTL_H 20 | #include 21 | #endif 22 | 23 | #ifdef HAVE_SYS_MMAN_H 24 | #include 25 | #endif 26 | 27 | #ifdef HAVE_SYS_STAT_H 28 | #include 29 | #endif 30 | 31 | #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) 32 | #define MAP_ANONYMOUS MAP_ANON 33 | #endif /* defined(MAP_ANON) && !defined(MAP_ANONYMOUS) */ 34 | 35 | static inline void * 36 | AllocateSpaceWithMMAP(size_t Size, bool UseNoReserve = false) { 37 | // NOTE: this assumes Size is a multiple of the page size. 38 | int FD = -1; 39 | #ifdef NEED_DEV_ZERO_FOR_MMAP 40 | static int DevZeroFD = open("/dev/zero", O_RDWR); 41 | if (DevZeroFD == -1) { 42 | perror("Can't open /dev/zero device"); 43 | abort(); 44 | } 45 | FD = zero_fd; 46 | #endif 47 | 48 | int Flags = MAP_PRIVATE | MAP_ANONYMOUS; 49 | #ifdef MAP_NORESERVE 50 | if (UseNoReserve) 51 | Flags |= MAP_NORESERVE; 52 | #endif 53 | 54 | void *Mem = ::mmap(0, Size, PROT_READ|PROT_WRITE, Flags, FD, 0); 55 | assert(Mem != MAP_FAILED && "couldn't get space!"); 56 | return Mem; 57 | } 58 | -------------------------------------------------------------------------------- /include/poolalloc_runtime/test.ex: -------------------------------------------------------------------------------- 1 | #include "PoolAllocator.h" 2 | #include 3 | 4 | PoolAllocator > a(10, 16); 5 | PoolAllocator > b(8, 8); 6 | 7 | PoolAllocator, MallocSlabManager<> > > c(8, 8); 8 | 9 | RangeSplayMap ma; 10 | 11 | int main() { 12 | void* x = a.alloc(); 13 | std::cerr << a.isAllocated(x) << " " << a.isAllocated((char*)x + 5) << " " << a.isAllocated((char*)x + 10) << "\n"; 14 | a.dealloc(x); 15 | 16 | x = b.alloc(); 17 | std::cerr << b.isAllocated(x) << " " << b.isAllocated((char*)x + 5) << " " << b.isAllocated((char*)x + 10) << "\n"; 18 | b.dealloc(x); 19 | 20 | x = c.alloc(); 21 | std::cerr << c.isAllocated(x) << " " << c.isAllocated((char*)x + 5) << " " << c.isAllocated((char*)x + 10) << "\n"; 22 | void* y = c.alloc(4); 23 | std::cerr << c.isAllocated(y) << " " << c.isAllocated((char*)y + 5) << " " << c.isAllocated((char*)y + 10) << " " << c.isAllocated((char*)y + 50) << "\n"; 24 | c.dealloc(x); 25 | c.dealloc(y); 26 | 27 | unsigned asdf = 2; 28 | ma.insert((void*)0, (void*)1, asdf); 29 | 30 | return 0; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /lib/AssistDS/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | ArgCast.cpp 3 | ArgSimplify.cpp 4 | DSNodeEquivs.cpp 5 | Devirt.cpp 6 | DynCount.cpp 7 | FuncSimplify.cpp 8 | FuncSpec.cpp 9 | GEPExprArgs.cpp 10 | IndCloner.cpp 11 | Int2PtrCmp.cpp 12 | LoadArgs.cpp 13 | MergeGEP.cpp 14 | SVADevirt.cpp 15 | SimplifyExtractValue.cpp 16 | SimplifyGEP.cpp 17 | SimplifyInsertValue.cpp 18 | SimplifyLoad.cpp 19 | StructReturnToPointer.cpp 20 | TypeChecks.cpp 21 | TypeChecksOpt.cpp 22 | ) 23 | 24 | # Build both shared and static libs 25 | # Also, drop the 'lib' suffix to match how 26 | # the Makefile-driven version functions. 27 | 28 | if( NOT WIN32 AND LLVM_ENABLE_PIC ) 29 | set(bsl ${BUILD_SHARED_LIBS}) 30 | set(BUILD_SHARED_LIBS ON) 31 | add_llvm_library(AssistDS ${SOURCES}) 32 | set(BUILD_SHARED_LIBS ${bsl}) 33 | set_property(TARGET AssistDS PROPERTY OUTPUT_NAME "AssistDS") 34 | set_property(TARGET AssistDS PROPERTY PREFIX "") 35 | set(AssistDS_STATIC_TARGET AssistDS_static) 36 | add_dependencies(AssistDS intrinsics_gen) 37 | else() 38 | set(AssistDS_STATIC_TARGET AssistDS) 39 | endif() 40 | 41 | if( NOT BUILD_SHARED_LIBS ) 42 | add_llvm_library(${AssistDS_STATIC_TARGET} ${SOURCES}) 43 | set_property(TARGET ${AssistDS_STATIC_TARGET} PROPERTY OUTPUT_NAME "AssistDS") 44 | set_property(TARGET ${AssistDS_STATIC_TARGET} PROPERTY PREFIX "") 45 | add_dependencies(${AssistDS_STATIC_TARGET} intrinsics_gen) 46 | endif() 47 | -------------------------------------------------------------------------------- /lib/AssistDS/FuncSimplify.cpp: -------------------------------------------------------------------------------- 1 | //===-------- FuncSimplify.cpp - Replace Global Aliases -------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | //===----------------------------------------------------------------------===// 10 | #define DEBUG_TYPE "func-simplify" 11 | 12 | #include "assistDS/FuncSimplify.h" 13 | #include "llvm/IR/Attributes.h" 14 | #include "llvm/Transforms/Utils/Cloning.h" 15 | #include "llvm/ADT/Statistic.h" 16 | #include "llvm/Support/FormattedStream.h" 17 | #include "llvm/Support/Debug.h" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace llvm; 24 | 25 | // Pass statistics 26 | STATISTIC(numChanged, "Number of aliases deleted"); 27 | 28 | // 29 | // Method: runOnModule() 30 | // 31 | // Description: 32 | // Entry point for this LLVM pass. 33 | // Replace all internal aliases with the 34 | // aliasee value 35 | // 36 | // Inputs: 37 | // M - A reference to the LLVM module to transform 38 | // 39 | // Outputs: 40 | // M - The transformed LLVM module. 41 | // 42 | // Return value: 43 | // true - The module was modified. 44 | // false - The module was not modified. 45 | // 46 | bool FuncSimplify::runOnModule(Module& M) { 47 | 48 | std::vector toDelete; 49 | for (Module::alias_iterator I = M.alias_begin(); I != M.alias_end(); ++I) { 50 | if(!I->hasInternalLinkage()) 51 | continue; 52 | I->replaceAllUsesWith(I->getAliasee()); 53 | toDelete.push_back(I); 54 | } 55 | numChanged += toDelete.size(); 56 | 57 | while(!toDelete.empty()) { 58 | GlobalAlias *I = toDelete.back(); 59 | toDelete.pop_back(); 60 | I->eraseFromParent(); 61 | } 62 | 63 | 64 | return true; 65 | } 66 | 67 | // Pass ID variable 68 | char FuncSimplify::ID = 0; 69 | 70 | // Register the pass 71 | static RegisterPass 72 | X("func-simplify", "Delete Aliases"); 73 | -------------------------------------------------------------------------------- /lib/AssistDS/Makefile: -------------------------------------------------------------------------------- 1 | ##===- lib/AssistDS/Makefile -------------------------------*- Makefile -*-===## 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file was developed by the LLVM research group and is distributed under 6 | # the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | # 8 | ##===----------------------------------------------------------------------===## 9 | 10 | LEVEL = ../.. 11 | ifneq ($(OS),Cygwin) 12 | ifneq ($(OS),MingW) 13 | SHARED_LIBRARY=1 14 | LOADABLE_MODULE=1 15 | endif 16 | endif 17 | LIBRARYNAME = AssistDS 18 | BUILD_ARCHIVE=1 19 | 20 | include $(LEVEL)/Makefile.common 21 | 22 | CFlags += -Wno-deprecated 23 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Discover the projects that use CMake in the subdirectories. 2 | # Note that explicit cmake invocation is required every time a new project is 3 | # added or removed. 4 | file(GLOB entries *) 5 | foreach(entry ${entries}) 6 | if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt) 7 | add_subdirectory(${entry}) 8 | endif() 9 | endforeach(entry) 10 | -------------------------------------------------------------------------------- /lib/DSA/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | AddressTakenAnalysis.cpp 3 | AllocatorIdentification.cpp 4 | Basic.cpp 5 | BottomUpClosure.cpp 6 | CallTargets.cpp 7 | CompleteBottomUp.cpp 8 | DSCallGraph.cpp 9 | DSGraph.cpp 10 | DSTest.cpp 11 | DataStructure.cpp 12 | DataStructureStats.cpp 13 | EntryPointAnalysis.cpp 14 | EquivClassGraphs.cpp 15 | GraphChecker.cpp 16 | Local.cpp 17 | Printer.cpp 18 | SanityCheck.cpp 19 | StdLibPass.cpp 20 | TopDownClosure.cpp 21 | TypeSafety.cpp 22 | ) 23 | 24 | # Build both shared and static libs 25 | # Also, drop the 'lib' suffix to match how 26 | # the Makefile-driven version functions. 27 | 28 | if( NOT WIN32 AND LLVM_ENABLE_PIC ) 29 | set(bsl ${BUILD_SHARED_LIBS}) 30 | set(BUILD_SHARED_LIBS ON) 31 | add_llvm_library(LLVMDataStructure ${SOURCES}) 32 | set(BUILD_SHARED_LIBS ${bsl}) 33 | set_property(TARGET LLVMDataStructure PROPERTY OUTPUT_NAME "LLVMDataStructure") 34 | set_property(TARGET LLVMDataStructure PROPERTY PREFIX "") 35 | set(DSA_STATIC_TARGET LLVMDataStructure_static) 36 | add_dependencies(LLVMDataStructure intrinsics_gen) 37 | else() 38 | set(DSA_STATIC_TARGET LLVMDataStructure) 39 | endif() 40 | 41 | if( NOT BUILD_SHARED_LIBS ) 42 | add_llvm_library(${DSA_STATIC_TARGET} ${SOURCES}) 43 | set_property(TARGET ${DSA_STATIC_TARGET} PROPERTY OUTPUT_NAME "LLVMDataStructure") 44 | set_property(TARGET ${DSA_STATIC_TARGET} PROPERTY PREFIX "") 45 | add_dependencies(${DSA_STATIC_TARGET} intrinsics_gen) 46 | endif() 47 | -------------------------------------------------------------------------------- /lib/DSA/Makefile: -------------------------------------------------------------------------------- 1 | ##===- lib/DSA/Makefile ------------------------------------*- Makefile -*-===## 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file was developed by the LLVM research group and is distributed under 6 | # the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | # 8 | ##===----------------------------------------------------------------------===## 9 | 10 | LEVEL = ../.. 11 | LIBRARYNAME = LLVMDataStructure 12 | BUILD_ARCHIVE := 1 13 | ifneq ($(OS),Cygwin) 14 | ifneq ($(OS),MingW) 15 | SHARED_LIBRARY := 1 16 | LOADABLE_MODULE := 1 17 | endif 18 | endif 19 | 20 | include $(LEVEL)/Makefile.common 21 | 22 | CFlags += -Wno-deprecated 23 | 24 | -------------------------------------------------------------------------------- /lib/DSA/README: -------------------------------------------------------------------------------- 1 | DSA is changed since PLDI07 in (at least) the following ways: 2 | 3 | 1) DSA tracks types per offset. 4 | 2) DSA does not assume that all clients will want to collapse a node if types 5 | conflict. Many clients don't care that an offset is used as an int or a 6 | double, they just care about the points-to result. 7 | 8 | In Progress: 9 | 10 | 1) DSA handles multiple entry points in a module. 11 | 2) Optional assumption that only legal targets are called at indirect call sites 12 | 3) Positional arguments, rather than pointer relative arguments. This handles 13 | the case where pointer and ints are assumed compatible and function pointers 14 | containing them are cast freely. 15 | 16 | -------------------------------------------------------------------------------- /lib/Macroscopic/Makefile: -------------------------------------------------------------------------------- 1 | # Indicate where we are relative to the top of the source tree. 2 | LEVEL=../.. 3 | 4 | # Give the name of a library. This will build a dynamic version. 5 | ifneq ($(OS),Cygwin) 6 | ifneq ($(OS),MingW) 7 | SHARED_LIBRARY=1 8 | LOADABLE_MODULE = 1 9 | endif 10 | endif 11 | DONT_BUILD_RELINKED=1 12 | LIBRARYNAME=macroscopic 13 | 14 | # Include Makefile.common so we know what to do. 15 | include $(LEVEL)/Makefile.common 16 | 17 | -------------------------------------------------------------------------------- /lib/Macroscopic/README.txt: -------------------------------------------------------------------------------- 1 | //===- llvm-poolalloc/lib/Macroscopic -------------------------------------===// 2 | 3 | This directory contains an experimental implementation of several ideas for 4 | Macroscopic analyses and transformations, which may eventually include 5 | reimplementation of the pool allocator and other passes. 6 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Relative path to the top of the source tree. 3 | # 4 | LEVEL=.. 5 | 6 | # 7 | # List all of the subdirectories that we will compile. 8 | # 9 | DIRS=DSA PoolAllocate AssistDS 10 | 11 | include $(LEVEL)/Makefile.common 12 | -------------------------------------------------------------------------------- /lib/PoolAllocate/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | AccessTrace.cpp 3 | AllHeapNodesHeuristic.cpp 4 | AllNodesHeuristic.cpp 5 | Heuristic.cpp 6 | PAMultipleGlobalPool.cpp 7 | PASimple.cpp 8 | PointerCompress.cpp 9 | PoolAllocate.cpp 10 | PoolOptimize.cpp 11 | RunTimeAssociate.cpp 12 | TransformFunctionBody.cpp 13 | ) 14 | 15 | # Build both shared and static libs 16 | # Also, drop the 'lib' suffix to match how 17 | # the Makefile-driven version functions. 18 | 19 | if( NOT WIN32 AND LLVM_ENABLE_PIC ) 20 | set(bsl ${BUILD_SHARED_LIBS}) 21 | set(BUILD_SHARED_LIBS ON) 22 | add_llvm_library(poolalloc ${SOURCES}) 23 | set(BUILD_SHARED_LIBS ${bsl}) 24 | set_property(TARGET poolalloc PROPERTY OUTPUT_NAME "poolalloc") 25 | set_property(TARGET poolalloc PROPERTY PREFIX "") 26 | set(PA_STATIC_TARGET poolalloc_static) 27 | add_dependencies(poolalloc intrinsics_gen) 28 | target_link_libraries(poolalloc LLVMDataStructure) 29 | else() 30 | set(PA_STATIC_TARGET poolalloc) 31 | endif() 32 | 33 | if( NOT BUILD_SHARED_LIBS ) 34 | add_llvm_library(${PA_STATIC_TARGET} ${SOURCES}) 35 | set_property(TARGET ${PA_STATIC_TARGET} PROPERTY OUTPUT_NAME "poolalloc") 36 | set_property(TARGET ${PA_STATIC_TARGET} PROPERTY PREFIX "") 37 | add_dependencies(${PA_STATIC_TARGET} intrinsics_gen) 38 | target_link_libraries(${PA_STATIC_TARGET} LLVMDataStructure) 39 | endif() 40 | -------------------------------------------------------------------------------- /lib/PoolAllocate/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Indicate where we are relative to the top of the source tree. 3 | # 4 | LEVEL=../.. 5 | 6 | # 7 | # Give the name of a library. This will build a dynamic version. 8 | # 9 | LIBRARYNAME=poolalloc 10 | BUILD_ARCHIVE := 1 11 | ifneq ($(OS),Cygwin) 12 | ifneq ($(OS),MingW) 13 | SHARED_LIBRARY := 1 14 | LOADABLE_MODULE := 1 15 | endif 16 | endif 17 | 18 | # 19 | # Include Makefile.common so we know what to do. 20 | # 21 | include $(LEVEL)/Makefile.common 22 | 23 | -------------------------------------------------------------------------------- /runtime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Discover the projects that use CMake in the subdirectories. 2 | # Note that explicit cmake invocation is required every time a new project is 3 | # added or removed. 4 | file(GLOB entries *) 5 | foreach(entry ${entries}) 6 | if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt) 7 | if(NOT ${entry} MATCHES "FreeListAllocator") 8 | add_subdirectory(${entry}) 9 | endif() 10 | endif() 11 | endforeach(entry) 12 | -------------------------------------------------------------------------------- /runtime/DynCount/DynCount.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long * Total = 0; 5 | static unsigned long * Safe = 0; 6 | 7 | static void 8 | printItAll (void) { 9 | FILE * fp = fopen ("lsstats", "w"); 10 | fprintf (fp, "%lu Safe \n", *Safe); 11 | fprintf (fp, "%lu Total \n", *Total); 12 | fflush (fp); 13 | fclose (fp); 14 | return; 15 | } 16 | 17 | void 18 | DYN_COUNT_setup (unsigned long * total, unsigned long * safe) { 19 | Total = total; 20 | Safe = safe; 21 | atexit (printItAll); 22 | return; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /runtime/DynCount/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME=count 3 | 4 | # 5 | # Build shared libraries on all platforms except Cygwin and MingW (which do 6 | # not support them). 7 | # 8 | ifneq ($(OS),Cygwin) 9 | ifneq ($(OS),MingW) 10 | SHARED_LIBRARY=1 11 | endif 12 | endif 13 | 14 | ifeq ($(OS),Linux) 15 | CXX.Flags += -march=native 16 | else 17 | CXX.Flags += -march=nocona 18 | endif 19 | 20 | CXX.Flags += -fno-threadsafe-statics 21 | 22 | # 23 | # Do not build bitcode library on Mac OS X; XCode will pre-install llvm-gcc, 24 | # and that can cause the build to fail if it doesn't match the current version 25 | # of LLVM. 26 | # 27 | ifneq ($(OS),Darwin) 28 | #BYTECODE_LIBRARY=1 29 | endif 30 | 31 | include $(LEVEL)/Makefile.common 32 | 33 | # Always build optimized and debug versions 34 | all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG) 35 | -------------------------------------------------------------------------------- /runtime/DynamicTypeChecks/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME = typechecks_rt 3 | 4 | # 5 | # Don't build shared libraries on Windows. Note that we need to specify 6 | # both SHARED_LIBRARY and LOADABLE_MODULE on Mac OS X. 7 | # 8 | ifneq ($(OS),Cygwin) 9 | ifneq ($(OS),MingW) 10 | SHARED_LIBRARY=1 11 | LOADABLE_MODULE := 1 12 | endif 13 | endif 14 | 15 | ifdef ENABLE_OPTIMIZED 16 | CXXFLAGS += -DNDEBUG=1 17 | endif 18 | 19 | # 20 | # Do not build bitcode library on Mac OS X; XCode will pre-install llvm-gcc, 21 | # and that can cause the build to fail if it doesn't match the current version 22 | # of LLVM. 23 | # 24 | ifneq ($(OS),Darwin) 25 | #BYTECODE_LIBRARY=1 26 | endif 27 | 28 | include $(LEVEL)/Makefile.common 29 | 30 | # Always build optimized and debug versions 31 | all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG) 32 | -------------------------------------------------------------------------------- /runtime/FL2Allocator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(/localhome/simmon12/progs/dyncall-0.5/dyncall) 2 | link_directories(/localhome/simmon12/progs/dyncall-0.5/dyncall/build_out/linux_x86_gcc_release) 3 | add_llvm_library( poolalloc_rt PoolAllocator.cpp ) 4 | set_property( 5 | TARGET poolalloc_rt 6 | PROPERTY COMPILE_DEFINITIONS 7 | ) 8 | target_link_libraries( poolalloc_rt dyncall_s ) 9 | -------------------------------------------------------------------------------- /runtime/FL2Allocator/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME=poolalloc_rt 3 | 4 | # 5 | # Build shared libraries on all platforms except Cygwin and MingW (which do 6 | # not support them). 7 | # 8 | ifneq ($(OS),Cygwin) 9 | ifneq ($(OS),MingW) 10 | SHARED_LIBRARY=1 11 | endif 12 | endif 13 | 14 | ifdef ENABLE_OPTIMIZED 15 | CXXFLAGS += -DNDEBUG=1 16 | endif 17 | 18 | CXXFLAGS += -fno-exceptions 19 | 20 | # 21 | # Do not build bitcode library on Mac OS X; XCode will pre-install llvm-gcc, 22 | # and that can cause the build to fail if it doesn't match the current version 23 | # of LLVM. 24 | # 25 | ifneq ($(OS),Darwin) 26 | #BYTECODE_LIBRARY=1 27 | endif 28 | 29 | include $(LEVEL)/Makefile.common 30 | 31 | 32 | -------------------------------------------------------------------------------- /runtime/FreeListAllocator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB sources *.cpp) 2 | add_llvm_library( poolalloc_fl_rt ${sources} ) -------------------------------------------------------------------------------- /runtime/FreeListAllocator/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME=poolalloc_fl_rt 3 | 4 | # 5 | # Build shared libraries on all platforms except Cygwin and MingW (which do 6 | # not support them). 7 | # 8 | ifneq ($(OS),Cygwin) 9 | ifneq ($(OS),MingW) 10 | #SHARED_LIBRARY=1 11 | #LOADABLE_MODULE := 1 12 | endif 13 | endif 14 | 15 | include $(LEVEL)/Makefile.common 16 | -------------------------------------------------------------------------------- /runtime/FreeListAllocator/PageManager.h: -------------------------------------------------------------------------------- 1 | //===- PageManager.h - Allocates memory on page boundaries ------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the interface used by the pool allocator to allocate memory 11 | // on large alignment boundaries. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef PAGEMANAGER_H 16 | #define PAGEMANAGER_H 17 | 18 | /// InitializePageManager - This function must be called before any other page 19 | /// manager accesses are performed. It may be called multiple times. 20 | /// 21 | unsigned int InitializePageManager(); 22 | 23 | /// PageSize - Contains the size of the unit of memory allocated by 24 | /// AllocatePage. This is a value that is typically several kilobytes in size, 25 | /// and is guaranteed to be a power of two. 26 | /// 27 | extern unsigned PageSize; 28 | 29 | /// AllocatePage - This function returns a chunk of memory with size and 30 | /// alignment specified by getPageSize(). 31 | void *AllocatePage(); 32 | 33 | /// FreePage - This function returns the specified page to the pagemanager for 34 | /// future allocation. 35 | void FreePage(void *Page); 36 | 37 | /// GetPages - Just allocate the specified pages on a page boundary. This is 38 | /// a hack for large arrays. 39 | void * GetPages (unsigned NumPages); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /runtime/FreeListAllocator/PoolAllocator.h: -------------------------------------------------------------------------------- 1 | //===- PoolAllocator.h - Pool allocator runtime interface file --*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the interface which is implemented by the LLVM pool 11 | // allocator runtime library. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef POOLALLOCATOR_RUNTIME_H 16 | #define POOLALLOCATOR_RUNTIME_H 17 | 18 | #include "PoolSlab.h" 19 | 20 | typedef struct PoolTy { 21 | #if 0 22 | // The size of a page on this system 23 | unsigned int PageSize; 24 | #endif 25 | 26 | // NodeSize - Keep track of the object size tracked by this pool 27 | unsigned NodeSize; 28 | 29 | // Maximum number of nodes per page 30 | unsigned int MaxNodesPerPage; 31 | 32 | // Pointer to the list of slabs allocated for this pool 33 | struct SlabHeader * Slabs; 34 | 35 | // Linked list of slabs used to hold arrays 36 | struct SlabHeader * ArraySlabs; 37 | 38 | // Pointer to the fast alloc array 39 | struct SlabHeader * FastArray; 40 | 41 | // Pointer to the free list of nodes 42 | struct NodePointer FreeList; 43 | 44 | #if 0 45 | // FreeablePool - Set to false if the memory from this pool cannot be freed 46 | // before destroy. 47 | // 48 | unsigned FreeablePool; 49 | #endif /* 0 */ 50 | } PoolTy; 51 | 52 | extern "C" { 53 | void poolinit(PoolTy *Pool, unsigned NodeSize); 54 | void poolmakeunfreeable(PoolTy *Pool); 55 | void pooldestroy(PoolTy *Pool); 56 | void *poolalloc(PoolTy *Pool, unsigned NodeSize); 57 | void poolfree(PoolTy *Pool, void *Node); 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /runtime/FreeListAllocator/README.txt: -------------------------------------------------------------------------------- 1 | This implementation of the pool allocator runtime library is not used, 2 | and is kept for historical reasons. Please use the FL2 allocator 3 | instead. 4 | -------------------------------------------------------------------------------- /runtime/HeapFrag/HeapFrag.c: -------------------------------------------------------------------------------- 1 | /*===- HeapFrag.c - Routine to fragment the heap --------------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines a function 'EnsureHeapFragmentation', which is used to 11 | // artificially fragment the heap, to show the value of pool allocator even for 12 | // silly benchmarks that never free memory and thus have no fragmentation at 13 | // all. 14 | // 15 | //===----------------------------------------------------------------------===*/ 16 | 17 | #include 18 | 19 | static void **AllocateNodes(unsigned N, unsigned Size) { 20 | void **Spine = (void**)malloc(N*sizeof(void*)); 21 | unsigned i; 22 | for (i = 0; i != N; ++i) 23 | Spine[i] = malloc(Size); 24 | return Spine; 25 | } 26 | 27 | static void DeallocateNodes(void **Spine, unsigned N, unsigned Stride) { 28 | unsigned i; 29 | for (i = 0; i < N; i += Stride) { 30 | free(Spine[i]); 31 | Spine[i] = 0; 32 | } 33 | } 34 | 35 | 36 | void EnsureHeapFragmentation() { 37 | void **DS1 = AllocateNodes(10000, 16); 38 | void **DS2; 39 | void *A, *B, *C; 40 | DeallocateNodes(DS1+9000, 1000, 1); /* Free last elements */ 41 | DS2 = AllocateNodes(40000, 40); 42 | DeallocateNodes(DS1, 9000, 2); 43 | DeallocateNodes(DS2, 40000, 2); 44 | DS1 = AllocateNodes(2000, 8); 45 | DeallocateNodes(DS1, 2000, 2); 46 | DeallocateNodes(DS1, 2000, 3); 47 | } 48 | -------------------------------------------------------------------------------- /runtime/HeapFrag/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME=heapfrag 3 | 4 | # 5 | # Build shared libraries on all platforms except Cygwin and MingW (which do 6 | # not support them). 7 | # 8 | ifneq ($(OS),Cygwin) 9 | ifneq ($(OS),MingW) 10 | #SHARED_LIBRARY=1 11 | endif 12 | endif 13 | 14 | # 15 | # Do not build bitcode library on Mac OS X; XCode will pre-install llvm-gcc, 16 | # and that can cause the build to fail if it doesn't match the current version 17 | # of LLVM. 18 | # 19 | ifneq ($(OS),Darwin) 20 | BYTECODE_LIBRARY=1 21 | endif 22 | 23 | include $(LEVEL)/Makefile.common 24 | 25 | # Always build optimized and debug versions 26 | all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG) 27 | -------------------------------------------------------------------------------- /runtime/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Relative path to the top of the source tree. 3 | # 4 | LEVEL=.. 5 | 6 | # 7 | # List all of the subdirectories that we will compile. 8 | # 9 | DIRS=FreeListAllocator FL2Allocator PreRT DynCount DynamicTypeChecks 10 | 11 | include $(LEVEL)/Makefile.common 12 | -------------------------------------------------------------------------------- /runtime/PoolAllocator/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME=poolalloc_rt_old 3 | 4 | # 5 | # Build shared libraries on all platforms except Cygwin and MingW (which do 6 | # not support them). 7 | # 8 | ifneq ($(OS),Cygwin) 9 | ifneq ($(OS),MingW) 10 | SHARED_LIBRARY=1 11 | endif 12 | endif 13 | 14 | include $(LEVEL)/Makefile.common 15 | 16 | # Always build optimized and debug versions 17 | all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG) 18 | -------------------------------------------------------------------------------- /runtime/PoolAllocator/PageManager.h: -------------------------------------------------------------------------------- 1 | //===- PageManager.h - Allocates memory on page boundaries ------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the interface used by the pool allocator to allocate memory 11 | // on large alignment boundaries. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef PAGEMANAGER_H 16 | #define PAGEMANAGER_H 17 | 18 | /// InitializePageManager - This function must be called before any other page 19 | /// manager accesses are performed. It may be called multiple times. 20 | /// 21 | void InitializePageManager(); 22 | 23 | /// PageSize - Contains the size of the unit of memory allocated by 24 | /// AllocatePage. This is a value that is typically several kilobytes in size, 25 | /// and is guaranteed to be a power of two. 26 | /// 27 | extern unsigned PageSize; 28 | 29 | /// AllocatePage - This function returns a chunk of memory with size and 30 | /// alignment specified by getPageSize(). 31 | void *AllocatePage(); 32 | 33 | /// AllocateNPages - 34 | void *AllocateNPages(unsigned Num); 35 | 36 | /// FreePage - This function returns the specified page to the pagemanager for 37 | /// future allocation. 38 | void FreePage(void *Page); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /runtime/PoolAllocator/PoolAllocator.h: -------------------------------------------------------------------------------- 1 | //===- PoolAllocator.h - Pool allocator runtime interface file --*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file was developed by the LLVM research group and is distributed under 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the interface which is implemented by the LLVM pool 11 | // allocator runtime library. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef POOLALLOCATOR_RUNTIME_H 16 | #define POOLALLOCATOR_RUNTIME_H 17 | 18 | typedef struct PoolTy { 19 | // Ptr1, Ptr2 - Implementation specified data pointers. 20 | void *Ptr1, *Ptr2; 21 | 22 | // NodeSize - Keep track of the object size tracked by this pool 23 | unsigned NodeSize; 24 | 25 | // FreeablePool - Set to false if the memory from this pool cannot be freed 26 | // before destroy. 27 | // 28 | unsigned FreeablePool; 29 | } PoolTy; 30 | 31 | extern "C" { 32 | void poolinit(PoolTy *Pool, unsigned NodeSize); 33 | void poolmakeunfreeable(PoolTy *Pool); 34 | void pooldestroy(PoolTy *Pool); 35 | void *poolalloc(PoolTy *Pool, unsigned NumBytes); 36 | void poolfree(PoolTy *Pool, void *Node); 37 | void poolcheck(PoolTy *Pool, void *Node); 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /runtime/PreRT/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB sources *.cpp *.c) 2 | add_llvm_library( pa_pre_rt ${sources} ) 3 | -------------------------------------------------------------------------------- /runtime/PreRT/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL = ../.. 2 | LIBRARYNAME=pa_pre_rt 3 | 4 | # 5 | # Do not build bitcode library on Mac OS X; XCode will pre-install llvm-gcc, 6 | # and that can cause the build to fail if it doesn't match the current version 7 | # of LLVM. 8 | # 9 | ifneq ($(OS),Darwin) 10 | #BYTECODE_LIBRARY=1 11 | endif 12 | 13 | include $(LEVEL)/Makefile.common 14 | 15 | -------------------------------------------------------------------------------- /runtime/PreRT/strdup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #undef strdup 5 | #undef __strdup 6 | 7 | char* strdup(const char *s) 8 | { 9 | size_t len = strlen (s) + 1; 10 | void *new = malloc (len); 11 | 12 | if (new == NULL) 13 | return NULL; 14 | 15 | return (char *) memcpy (new, s, len); 16 | } 17 | 18 | char* __strdup(const char *s) 19 | { 20 | size_t len = strlen (s) + 1; 21 | void *new = malloc (len); 22 | 23 | if (new == NULL) 24 | return NULL; 25 | 26 | return (char *) memcpy (new, s, len); 27 | } 28 | -------------------------------------------------------------------------------- /runtime/README.txt: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | This directory contains the pool allocator runtime library implementations. 3 | 4 | The only fully maintained runtime library implementation is in the FL2Allocator 5 | directory. This supports the pool allocator, the bump pointer optimization, 6 | and the pointer compression runtime. 7 | 8 | The implementation in the FreeListAllocator directory is much slower than 9 | the FL2Allocator and has not been updated. 10 | 11 | The implementation in the PoolAllocator directory is also probably out of date, 12 | and is much slower than FL2, but is used by the SAFECode project, which cannot 13 | allow pool metadata to be stored intermixed with program data. 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Test runner infrastructure for PoolAlloc/DSA. This configures the PA test trees 2 | # for use by Lit, and delegates to LLVM's lit test handlers. 3 | 4 | set(PROJ_SRC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/..") 5 | set(PROJ_OBJ_ROOT "${CMAKE_CURRENT_BINARY_DIR}/..") 6 | 7 | configure_lit_site_cfg( 8 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in 9 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg 10 | ) 11 | 12 | if( PATH_TO_LLVM_BUILD ) 13 | set(POOLALLOC_TEST_EXTRA_ARGS "--path=${CMAKE_CURRENT_BINARY_DIR}/tools/") 14 | endif() 15 | 16 | option(POOLALLOC_TEST_USE_VG "Run PoolAlloc/DSA tests under Valgrind" OFF) 17 | if(POOLALLOC_TEST_USE_VG) 18 | set(POOLALLOC_TEST_EXTRA_ARGS ${POOLALLOC_TEST_EXTRA_ARGS} "--vg") 19 | endif () 20 | 21 | set(POOLALLOC_TEST_DEPS 22 | clang opt FileCheck llc not 23 | LLVMDataStructure AssistDS 24 | poolalloc poolalloc_rt 25 | ) 26 | 27 | # TODO: Add LLVM_INCLUDE_TESTS support? 28 | #if(LLVM_INCLUDE_TESTS) 29 | # list(APPEND CLANG_TEST_DEPS ClangUnitTests) 30 | # list(APPEND CLANG_TEST_PARAMS 31 | # clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg 32 | # ) 33 | 34 | add_lit_testsuite(check-poolalloc "Running the PoolAlloc/DSA regression tests" 35 | ${CMAKE_CURRENT_BINARY_DIR} 36 | DEPENDS ${POOLALLOC_TEST_DEPS} 37 | ARGS ${POOLALLOC_TEST_EXTRA_ARGS} 38 | ) 39 | set_target_properties(check-poolalloc PROPERTIES FOLDER "PoolAlloc/DSA tests") 40 | -------------------------------------------------------------------------------- /test/TEST.dsgraph.gnuplot: -------------------------------------------------------------------------------- 1 | ## set size square 0.5,0.5 2 | ## set key left top 3 | set nokey 4 | set pointsize 3 5 | 6 | set terminal postscript 7 | 8 | 9 | ##------- log(Time) vs. log(MemOps) -------- 10 | set output "runtimes.timeVmem.ps" 11 | set logscale xy 12 | #set xrange [5:50000] 13 | #set yrange [0.0005:5] 14 | set xlabel "Total Memory Operations" "TimesRoman,24" 15 | set ylabel "Execution time (sec)" "TimesRoman,24" 16 | plot 'timeVmem.txt' title "Time vs. Memory Ops" 17 | #replot 0.000002 * x * log10(x) 18 | 19 | ##------- log(Time) vs. log(LOC) -------- 20 | set output "runtimes.timeloc.ps" 21 | set logscale xy 22 | #set xrange [10:100000] 23 | #set yrange [0.0005:5] 24 | set xlabel "Lines of Code" "TimesRoman,24" 25 | set ylabel "Execution time (sec)" "TimesRoman,24" 26 | plot 'timeVloc.txt' title "Time vs. LOC" 27 | replot 0.000002 * x * log10(x) 28 | 29 | set terminal png 30 | 31 | ##------- log(Time) vs. log(MemOps) -------- 32 | set output "runtimes.timeVmem.png" 33 | set logscale xy 34 | #set xrange [5:50000] 35 | #set yrange [0.0005:5] 36 | set xlabel "Total Memory Operations" "TimesRoman,24" 37 | set ylabel "Execution time (sec)" "TimesRoman,24" 38 | plot 'timeVmem.txt' title "Time vs. Memory Ops" 39 | #replot 0.000002 * x * log10(x) 40 | 41 | ##------- log(Time) vs. log(LOC) -------- 42 | set output "runtimes.timeloc.png" 43 | set logscale xy 44 | #set xrange [10:100000] 45 | #set yrange [0.0005:5] 46 | set xlabel "Lines of Code" "TimesRoman,24" 47 | set ylabel "Execution time (sec)" "TimesRoman,24" 48 | plot 'timeVloc.txt' title "Time vs. LOC" 49 | replot 0.000002 * x * log10(x) 50 | 51 | 52 | 53 | 54 | ##------- log(Time/LOC) vs. log(LOC) -------- 55 | set nologscale y 56 | set logscale x 57 | set xrange [100:100000] 58 | set yrange [2:20] 59 | set xlabel "Lines of Code" "TimesRoman,24" 60 | set ylabel "Time/Line (microsec/line)" "TimesRoman,24" 61 | #set output "runtimes.timelocratio.ps" 62 | #plot '< ./runtimes.awk -v PlotTimeLOCRatio=1 data.txt' title "Time vs. LOC" 63 | 64 | ##------- log(Memory) vs. log(LOC) -------- 65 | set logscale xy 66 | set yrange [10:10000] 67 | set xlabel "Lines of Code" "TimesRoman,24" 68 | set ylabel "Total Memory (KB)" "TimesRoman,24" 69 | #set output "runtimes.memloc.ps" 70 | #plot '< ./runtimes.awk -v PlotMemLOC=1 data.txt' title "Time vs. LOC" 71 | -------------------------------------------------------------------------------- /test/TEST.strace.Makefile: -------------------------------------------------------------------------------- 1 | ##===- poolalloc/TEST.strace.Makefile ----------------------*- Makefile -*-===## 2 | # 3 | # Makefile for measuring system call activity with strace 4 | # 5 | ##===----------------------------------------------------------------------===## 6 | 7 | TESTNAME = $* 8 | CURDIR := $(shell cd .; pwd) 9 | PROGDIR := $(shell cd $(LLVM_SRC_ROOT)/projects/llvm-test; pwd)/ 10 | RELDIR := $(subst $(PROGDIR),,$(CURDIR)) 11 | 12 | STRACE := strace -c -f 13 | 14 | # 15 | # Once the results are generated, create files containing each individiual 16 | # piece of performance information. 17 | # 18 | 19 | # 20 | # Generate events for Pool Allocated CBE 21 | # 22 | $(PROGRAMS_TO_TEST:%=Output/test.$(TEST).pa.%): \ 23 | Output/test.$(TEST).pa.%: Output/%.poolalloc.cbe Output/test.$(TEST).% 24 | @echo "=========================================" 25 | @echo "Running '$(TEST)' test on '$(TESTNAME)' program" 26 | ifeq ($(RUN_OPTIONS),) 27 | $(VERB) cat $(STDIN_FILENAME) | $(STRACE) -o $@ $< 28 | else 29 | $(VERB) cat $(STDIN_FILENAME) | $(STRACE) -o $@ $< $(RUN_OPTIONS) 30 | endif 31 | 32 | # 33 | # Generate events for CBE 34 | # 35 | $(PROGRAMS_TO_TEST:%=Output/test.$(TEST).%): \ 36 | Output/test.$(TEST).%: Output/%.cbe 37 | @echo "=========================================" 38 | @echo "Running '$(TEST)' test on '$(TESTNAME)' program" 39 | ifeq ($(RUN_OPTIONS),) 40 | $(VERB) cat $(STDIN_FILENAME) | $(STRACE) -o $@ $< 41 | else 42 | $(VERB) cat $(STDIN_FILENAME) | $(STRACE) -o $@ $< $(RUN_OPTIONS) 43 | endif 44 | 45 | $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ 46 | Output/%.$(TEST).report.txt: Output/test.$(TEST).pa.% Output/test.$(TEST).% 47 | touch $@ 48 | 49 | $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ 50 | test.$(TEST).%: Output/%.$(TEST).report.txt 51 | @echo "---------------------------------------------------------------" 52 | @echo ">>> ========= '$(RELDIR)/$*' Program" 53 | @echo "---------------------------------------------------------------" 54 | @cat $< 55 | 56 | -------------------------------------------------------------------------------- /test/dsa/callgraph/addrtaken_caller.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=run_func,f1 2 | ;RUN: dsaopt %s -dsa-td -analyze -check-not-callees=run_func,main2 3 | 4 | ;XFAIL: * 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | @.str = private unnamed_addr constant [10 x i8] c"Main: %p\0A\00", align 1 9 | @.str1 = private unnamed_addr constant [10 x i8] c"Sum: %d\0A\00", align 1 10 | 11 | ; Function Attrs: nounwind uwtable 12 | define internal i32 @main(i32 %argc, i8** %argv) #0 { 13 | entry: 14 | %call = call i32 @main2(i32 %argc, i8** %argv) 15 | ret i32 %call 16 | } 17 | 18 | define internal i32 @main2(i32 %argc, i8** %argv) #0 { 19 | entry: 20 | %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i32 (i32, i8**)* @main2) 21 | %call1 = call i32 @foo() 22 | %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str1, i32 0, i32 0), i32 %call1) 23 | ret i32 0 24 | } 25 | 26 | declare i32 @printf(i8*, ...) 27 | 28 | ; Function Attrs: noinline nounwind uwtable 29 | define internal i32 @foo() #1 { 30 | entry: 31 | %call = call i32 @run_func(i32 (i32, i32)* @f1, i32 1, i32 2) 32 | ret i32 %call 33 | } 34 | 35 | ; Function Attrs: noinline nounwind uwtable 36 | define internal i32 @run_func(i32 (i32, i32)* %fptr, i32 %arg1, i32 %arg2) #1 { 37 | entry: 38 | %call = call i32 %fptr(i32 %arg1, i32 %arg2) 39 | ret i32 %call 40 | } 41 | 42 | ; Function Attrs: noinline nounwind uwtable 43 | define internal i32 @f1(i32 %arg1, i32 %arg2) #1 { 44 | entry: 45 | %add = add nsw i32 %arg1, %arg2 46 | ret i32 %add 47 | } 48 | 49 | attributes #0 = { nounwind uwtable } 50 | attributes #1 = { noinline nounwind uwtable } 51 | -------------------------------------------------------------------------------- /test/dsa/callgraph/addrtaken_main.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=run_func,f1 2 | ;RUN: dsaopt %s -dsa-td -analyze -check-not-callees=run_func,main 3 | 4 | ;XFAIL: * 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | @.str = private unnamed_addr constant [10 x i8] c"Main: %p\0A\00", align 1 9 | @.str1 = private unnamed_addr constant [10 x i8] c"Sum: %d\0A\00", align 1 10 | 11 | ; Function Attrs: nounwind uwtable 12 | define internal i32 @main(i32 %argc, i8** %argv) #0 { 13 | entry: 14 | %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i32 (i32, i8**)* @main) 15 | %call1 = call i32 @foo() 16 | %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str1, i32 0, i32 0), i32 %call1) 17 | ret i32 0 18 | } 19 | 20 | declare i32 @printf(i8*, ...) 21 | 22 | ; Function Attrs: noinline nounwind uwtable 23 | define internal i32 @foo() #1 { 24 | entry: 25 | %call = call i32 @run_func(i32 (i32, i32)* @f1, i32 1, i32 2) 26 | ret i32 %call 27 | } 28 | 29 | ; Function Attrs: noinline nounwind uwtable 30 | define internal i32 @run_func(i32 (i32, i32)* %fptr, i32 %arg1, i32 %arg2) #1 { 31 | entry: 32 | %call = call i32 %fptr(i32 %arg1, i32 %arg2) 33 | ret i32 %call 34 | } 35 | 36 | ; Function Attrs: noinline nounwind uwtable 37 | define internal i32 @f1(i32 %arg1, i32 %arg2) #1 { 38 | entry: 39 | %add = add nsw i32 %arg1, %arg2 40 | ret i32 %add 41 | } 42 | 43 | attributes #0 = { nounwind uwtable } 44 | attributes #1 = { noinline nounwind uwtable } 45 | -------------------------------------------------------------------------------- /test/dsa/callgraph/calltarget_basic.ll: -------------------------------------------------------------------------------- 1 | ; Very basic -calltarget-{,eq}td pass testing. 2 | 3 | ;RUN: dsaopt %s -calltarget-td -analyze | FileCheck %s 4 | ;RUN: dsaopt %s -calltarget-eqtd -analyze | FileCheck %s 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | ; Notes: 9 | ; * "A" and "B" are in an SCC so callgraph reports both when 10 | ; calling one of them. 11 | ; * Both calls in @B are reported to potentially call A and 12 | ; C due to lack of flow-sensitivity. 13 | 14 | define internal void @C() nounwind { 15 | entry: 16 | ret void 17 | } 18 | 19 | define internal void @A() nounwind { 20 | entry: 21 | ; indirect call to B() 22 | %Bfp = alloca void ()* 23 | store void ()* @B, void ()** %Bfp, align 8 24 | %B = load void ()*, void ()** %Bfp, align 8 25 | 26 | ;CHECK-DAG: call void %B() #0: A B 27 | call void %B() nounwind 28 | ret void 29 | } 30 | 31 | define internal void @B() nounwind { 32 | entry: 33 | %fp = alloca void ()* 34 | 35 | ; indirect call to A() 36 | store void ()* @A, void ()** %fp, align 8 37 | %A = load void ()*, void ()** %fp, align 8 38 | ;CHECK-DAG: call void %A() #0: A B C 39 | call void %A() nounwind 40 | 41 | ; indirect call to C() 42 | store void ()* @C, void ()** %fp, align 8 43 | %C = load void ()*, void ()** %fp, align 8 44 | ;CHECK-DAG: call void %C() #0: A B C 45 | call void %C() nounwind 46 | ret void 47 | } 48 | 49 | -------------------------------------------------------------------------------- /test/dsa/callgraph/chain.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=A,B 2 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=B,C 3 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=A,B 4 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=B,C 5 | 6 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 7 | target triple = "x86_64-unknown-linux-gnu" 8 | 9 | define void @C() { 10 | entry: 11 | ret void 12 | } 13 | 14 | define void @B() { 15 | entry: 16 | call void @C() 17 | ret void 18 | } 19 | 20 | define void @A() { 21 | entry: 22 | call void @B() 23 | ret void 24 | } 25 | -------------------------------------------------------------------------------- /test/dsa/callgraph/decode.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=decode,C2 2 | ;RUN: dsaopt %s -dsa-td -analyze -check-not-callees=decode,A1,B2,main,decode 3 | 4 | ;XFAIL: * 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | %struct.msg = type { void (i32, i32)*, i32 } 9 | 10 | @q = common global void (i32)* null, align 8 11 | 12 | ; Function Attrs: nounwind uwtable 13 | define i32 @main() #0 { 14 | entry: 15 | %call = call noalias i8* @malloc(i64 16) #2 16 | %0 = bitcast i8* %call to %struct.msg* 17 | store void (i32)* @A1, void (i32)** @q, align 8 18 | %p = getelementptr inbounds %struct.msg, %struct.msg* %0, i32 0, i32 0 19 | store void (i32, i32)* @B2, void (i32, i32)** %p, align 8 20 | call void @decode(void (i32, i32)* @C2) 21 | ret i32 0 22 | } 23 | 24 | ; Function Attrs: nounwind 25 | declare noalias i8* @malloc(i64) #1 26 | 27 | ; Function Attrs: nounwind uwtable 28 | define internal void @A1(i32 %a) #0 { 29 | entry: 30 | ret void 31 | } 32 | 33 | ; Function Attrs: nounwind uwtable 34 | define internal void @B2(i32 %a, i32 %b) #0 { 35 | entry: 36 | ret void 37 | } 38 | 39 | ; Function Attrs: nounwind uwtable 40 | define internal void @decode(void (i32, i32)* %decoder_f) #0 { 41 | entry: 42 | call void %decoder_f(i32 1, i32 2) 43 | ret void 44 | } 45 | 46 | ; Function Attrs: nounwind uwtable 47 | define internal void @C2(i32 %a, i32 %b) #0 { 48 | entry: 49 | ret void 50 | } 51 | 52 | attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } 53 | attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" } 54 | attributes #2 = { nounwind } 55 | 56 | !llvm.ident = !{!0} 57 | 58 | !0 = !{!"clang version 3.7.0 (git@github.com:llvm-mirror/clang.git c7f06de7cf01e7552da38e08a0a410c71fbc6837) (git@github.com:llvm-mirror/llvm.git 1fd101c86df4dd321a53bdd80fe5ca106f3f76e2)"} 59 | -------------------------------------------------------------------------------- /test/dsa/callgraph/dstest_anynotall.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=main,A 2 | ;RUN: dsaopt %s -dsa-td -analyze -check-not-callees=main 3 | ; Verify -check-not-callee behavior as error if any not all 4 | ; specified callees are reported by the callgraph. 5 | ; Test this using an empty set of callees. 6 | ; ModuleID = 'calltargets.o' 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | define internal void @A() nounwind { 11 | entry: 12 | ret void 13 | } 14 | 15 | define internal void @B() nounwind { 16 | entry: 17 | ret void 18 | } 19 | 20 | define void @main() nounwind { 21 | entry: 22 | call void @A() nounwind 23 | ret void 24 | } 25 | 26 | -------------------------------------------------------------------------------- /test/dsa/callgraph/fptr.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=main,A 2 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=main,A 3 | 4 | ; ModuleID = 'fptr1.o' 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | define internal void @A(void (i8*)** %f) nounwind { 9 | entry: 10 | %f_addr = alloca void (i8*)** ; [#uses=1] 11 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 12 | store void (i8*)** %f, void (i8*)*** %f_addr 13 | br label %return 14 | 15 | return: ; preds = %entry 16 | ret void 17 | } 18 | 19 | define internal void @B(void (i8*)** %f) nounwind { 20 | entry: 21 | %f_addr = alloca void (i8*)** ; [#uses=1] 22 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 23 | store void (i8*)** %f, void (i8*)*** %f_addr 24 | br label %return 25 | 26 | return: ; preds = %entry 27 | ret void 28 | } 29 | 30 | define i32 @main() nounwind { 31 | entry: 32 | %retval = alloca i32 ; [#uses=1] 33 | %F = alloca void (i8*)* ; [#uses=3] 34 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 35 | store void (i8*)* bitcast (void (void (i8*)**)* @A to void (i8*)*), void (i8*)** %F, align 8 36 | %0 = load void (i8*)*, void (i8*)** %F, align 8 ; [#uses=1] 37 | %F1 = bitcast void (i8*)** %F to i8* ; [#uses=1] 38 | call void %0(i8* %F1) nounwind 39 | br label %return 40 | 41 | return: ; preds = %entry 42 | %retval2 = load i32, i32* %retval ; [#uses=1] 43 | ret i32 %retval2 44 | } 45 | -------------------------------------------------------------------------------- /test/dsa/callgraph/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/callgraph/loop1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef int* (*funcptr)(int *); 5 | 6 | funcptr FP; 7 | struct S { 8 | funcptr f; 9 | }; 10 | 11 | int * B() { 12 | } 13 | int * A() { 14 | } 15 | void D(funcptr f) { 16 | f = B; 17 | } 18 | int * SetFP(void * f){ 19 | D(FP); 20 | } 21 | 22 | static int * init() { 23 | FP = A; 24 | (*FP)(malloc(sizeof(int))); 25 | return (*FP)(malloc(sizeof(int))); 26 | } 27 | void init2(struct S *o){ 28 | o->f = B; 29 | } 30 | static void init1() { 31 | struct S * t = malloc(sizeof(struct S)); 32 | t->f = FP; 33 | init2(t); 34 | 35 | } 36 | 37 | int main() { 38 | init(); 39 | init1(); 40 | } 41 | -------------------------------------------------------------------------------- /test/dsa/callgraph/loop2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef int* (*funcptr)(int *); 5 | typedef int* (*funcptr2)(void *); 6 | 7 | funcptr FP; 8 | 9 | int * B() { 10 | } 11 | int * A() { 12 | } 13 | void D(funcptr f) { 14 | f = B; 15 | } 16 | int * SetFP(void * f){ 17 | D(FP); 18 | } 19 | 20 | int * init() { 21 | FP = A; 22 | funcptr2 setter = SetFP; 23 | (*setter)(malloc(3)); 24 | (*FP)(malloc(sizeof(int))); 25 | return (*FP)(malloc(sizeof(int))); 26 | } 27 | 28 | int main() { 29 | init(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test/dsa/callgraph/merge.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=E,B,D,A 2 | ; ModuleID = 'merge.o' 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | define internal void @A() nounwind { 7 | entry: 8 | call void @B() nounwind 9 | br label %return 10 | 11 | return: ; preds = %entry 12 | ret void 13 | } 14 | 15 | define internal void @B() nounwind { 16 | entry: 17 | call void @A() nounwind 18 | br label %return 19 | 20 | return: ; preds = %entry 21 | ret void 22 | } 23 | 24 | define internal void @C() nounwind { 25 | entry: 26 | call void @D() nounwind 27 | br label %return 28 | 29 | return: ; preds = %entry 30 | ret void 31 | } 32 | 33 | define internal void @D() nounwind { 34 | entry: 35 | call void @C() nounwind 36 | br label %return 37 | 38 | return: ; preds = %entry 39 | ret void 40 | } 41 | 42 | define internal void @E() nounwind { 43 | entry: 44 | %fp = alloca void ()* ; [#uses=3] 45 | %fp1 = alloca void ()* ; [#uses=1] 46 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 47 | store void ()* @B, void ()** %fp, align 8 48 | store void ()* @A, void ()** %fp1, align 8 49 | store void ()* @D, void ()** %fp, align 8 50 | %0 = load void ()*, void ()** %fp, align 8 ; [#uses=1] 51 | call void %0() nounwind 52 | br label %return 53 | 54 | return: ; preds = %entry 55 | ret void 56 | } 57 | -------------------------------------------------------------------------------- /test/dsa/callgraph/pr7799.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'test.opt.bc' 2 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=main,a,b 3 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=main,a,b 4 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" 5 | target triple = "x86_64-unknown-linux-gnu" 6 | 7 | %struct.combo = type { i8*, i32 (i32)* } 8 | 9 | @farray = internal global [2 x %struct.combo] [%struct.combo { i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0), i32 (i32)* @a }, %struct.combo { i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str1, i64 0, i64 0), i32 (i32)* @b }], align 32 ; <[2 x %struct.combo]*> [#uses=1] 10 | @.str = private constant [6 x i8] c"first\00", align 1 ; <[6 x i8]*> [#uses=1] 11 | @.str1 = private constant [7 x i8] c"second\00", align 1 ; <[7 x i8]*> [#uses=1] 12 | 13 | define internal i32 @a(i32 %x) nounwind { 14 | entry: 15 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 16 | %0 = add nsw i32 %x, %x ; [#uses=1] 17 | br label %return 18 | 19 | return: ; preds = %entry 20 | ret i32 %0 21 | } 22 | 23 | define internal i32 @b(i32 %x) nounwind { 24 | entry: 25 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 26 | %0 = mul i32 %x, %x ; [#uses=1] 27 | br label %return 28 | 29 | return: ; preds = %entry 30 | ret i32 %0 31 | } 32 | 33 | define i32 @main(i32 %argc, i8*** %argv) nounwind { 34 | entry: 35 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 36 | %0 = sext i32 %argc to i64 ; [#uses=1] 37 | %1 = getelementptr inbounds [2 x %struct.combo], [2 x %struct.combo]* @farray, i64 0, i64 %0 ; <%struct.combo*> [#uses=1] 38 | %2 = getelementptr inbounds %struct.combo, %struct.combo* %1, i32 0, i32 1 ; [#uses=1] 39 | %3 = load i32 (i32)*, i32 (i32)** %2, align 8 ; [#uses=1] 40 | %4 = call i32 %3(i32 %argc) nounwind ; [#uses=1] 41 | br label %return 42 | 43 | return: ; preds = %entry 44 | ret i32 %4 45 | } 46 | -------------------------------------------------------------------------------- /test/dsa/callgraph/scc.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=B,A 2 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=A,B 3 | ; ModuleID = 'scc.o' 4 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 5 | target triple = "x86_64-unknown-linux-gnu" 6 | 7 | define void @A() nounwind { 8 | entry: 9 | call void @B () nounwind 10 | br label %return 11 | 12 | return: ; preds = %entry 13 | ret void 14 | } 15 | 16 | define void @B() nounwind { 17 | entry: 18 | call void @A() nounwind 19 | br label %return 20 | 21 | return: ; preds = %entry 22 | ret void 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/dsa/callgraph/scc1.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=C,A,B 2 | 3 | ; ModuleID = 'scc.o' 4 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 5 | target triple = "x86_64-unknown-linux-gnu" 6 | 7 | define internal void @A() nounwind { 8 | entry: 9 | call void @B() nounwind 10 | br label %return 11 | 12 | return: ; preds = %entry 13 | ret void 14 | } 15 | 16 | define internal void @B() nounwind { 17 | entry: 18 | call void @A() nounwind 19 | br label %return 20 | 21 | return: ; preds = %entry 22 | ret void 23 | } 24 | 25 | define internal void @C() nounwind { 26 | entry: 27 | call void @A() nounwind 28 | call void @B() nounwind 29 | br label %return 30 | 31 | return: ; preds = %entry 32 | ret void 33 | } 34 | -------------------------------------------------------------------------------- /test/dsa/callgraph/scc3.c: -------------------------------------------------------------------------------- 1 | // A, B, func are in an SCC 2 | // C is called indirectly from A/B 3 | // The indirect call site in C is resolved, once we process the SCC 4 | // But since, we never process the SCC graph again, 5 | // we never inline func into the SCC graph(of A, B, and func) at that 6 | // call site. 7 | 8 | // when we inline the SCCGraph into D(due to call to A), the unresolved 9 | // call site is also inlined. As it is complete and can be resolved 10 | // we inline the SCC graph again, pulling in the unresolved call site 11 | // again. This causes an infinte looping in BU. 12 | 13 | //RUN: clang %s -c -emit-llvm -o - | \ 14 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 15 | 16 | typedef int* (*funcptr)(int *); 17 | 18 | static int* A(void); 19 | 20 | static int* func(int * arg) { 21 | A(); 22 | return arg; 23 | } 24 | 25 | static int* C(funcptr f, int *arg) { 26 | (*f)(arg); 27 | } 28 | 29 | static int *B() { 30 | func(A()); 31 | return C(func, A()); 32 | } 33 | 34 | static int* A() { 35 | return func(B()); 36 | } 37 | 38 | static int* D() { 39 | return A(); 40 | } 41 | -------------------------------------------------------------------------------- /test/dsa/callgraph/scc3a.c: -------------------------------------------------------------------------------- 1 | // similiar to scc3. But with 2 SCCs 2 | 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | typedef int* (*funcptr)(int *); 8 | 9 | static int* A1(void); 10 | static int* A2(void); 11 | 12 | static int* func1(int * arg) { 13 | A1(); 14 | return arg; 15 | } 16 | static int* func2(int * arg) { 17 | A2(); 18 | return arg; 19 | } 20 | 21 | static int* C1(funcptr f, int *arg) { 22 | (*f)(arg); 23 | } 24 | static int* C2(funcptr f, int *arg) { 25 | (*f)(arg); 26 | } 27 | 28 | static int *B1() { 29 | func1(A1()); 30 | return C1(func2, A1()); 31 | } 32 | static int *B2() { 33 | func2(A2()); 34 | return C2(func1, A2()); 35 | } 36 | static int* A1() { 37 | return func1(B1()); 38 | } 39 | 40 | static int* A2() { 41 | return func2(B2()); 42 | } 43 | 44 | static int* D() { 45 | A2(); 46 | return A1(); 47 | } 48 | -------------------------------------------------------------------------------- /test/dsa/callgraph/scc3b.c: -------------------------------------------------------------------------------- 1 | // A, B, C, func are in an SCC 2 | // C is called indirectly from B 3 | // The indirect call site in C is resolved, once we inline C into B. 4 | 5 | // But since, B and C are in the same graph, inlining C with B, 6 | // merges the arguments for C with the actual arguments passed in 7 | // from B. This makes the function pointer being called to be 8 | // marked incomplete(coming from argument). 9 | 10 | // when we inline the SCCGraph into D(due to call to A), the unresolved 11 | // call site is also inlined. As it is complete and can be resolved 12 | // we inline the SCC graph again, pulling in the unresolved call site 13 | // again. This causes an infinte looping in BU. 14 | // XFAIL:* 15 | // RUN: not 16 | #include 17 | 18 | typedef int* (*funcptr)(int *); 19 | 20 | static int* A(void); 21 | static int* B(void); 22 | static int* func(int*); 23 | static int* C(funcptr f, int *arg) ; 24 | 25 | static int* func(int * arg) { 26 | A(); 27 | return C(NULL, arg); 28 | } 29 | 30 | static int* C(funcptr f, int *arg) { 31 | A(); 32 | func(B()); 33 | (*f)(arg); 34 | } 35 | 36 | static int *B() { 37 | func(A()); 38 | return C(func, A()); 39 | } 40 | 41 | static int* A() { 42 | return C(NULL,func(B())); 43 | } 44 | 45 | static int* D() { 46 | return A(); 47 | } 48 | -------------------------------------------------------------------------------- /test/dsa/equivs/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/equivs/no-callees.ll: -------------------------------------------------------------------------------- 1 | ; Don't die if we don't know the callees 2 | ; RUN: adsaopt -disable-output -dsnodeequivs %s 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | @FP = external global i64 ()* 7 | 8 | define i64 @main(i32 %argc, i8** %argv) uwtable { 9 | entry: 10 | %fptr = load i64()*, i64()** @FP 11 | %0 = call i64 %fptr() 12 | ret i64 %0 13 | } 14 | -------------------------------------------------------------------------------- /test/dsa/equivs/undef-null-calls.ll: -------------------------------------------------------------------------------- 1 | ; Test call/invoke to null and undef (bugpoint) 2 | ; RUN: adsaopt -disable-output -dsnodeequivs %s 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | declare i32 @__gxx_personality_v0(...) 6 | 7 | define i64 @main(i32 %argc, i8** %argv) uwtable { 8 | entry: 9 | %0 = invoke i64 undef(i64 0) 10 | to label %cont unwind label %lpad 11 | 12 | cont: 13 | %1 = invoke i64 null(i64 %0) 14 | to label %done unwind label %lpad 15 | 16 | lpad: 17 | %2 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 18 | cleanup 19 | br label %done 20 | 21 | done: 22 | %retval = phi i64 [0, %lpad], [%1, %cont] 23 | %test = call i64 undef(i64 %retval) 24 | %test2 = call i64 null(i64 %test) 25 | ret i64 %retval 26 | } 27 | -------------------------------------------------------------------------------- /test/dsa/extern/extern2.ll: -------------------------------------------------------------------------------- 1 | ;Here we get a pointer from an external function and pass it to a callee. 2 | ;We then test that the flags on that pointer are set appropriately. 3 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:ptr+IE" 4 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "takesPointer:ptr+I-E" 5 | 6 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "main:ptr-I+E" 7 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "takesPointer:ptr+I-E" 8 | 9 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "main:ptr-I+E" 10 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "takesPointer:ptr-I+E" 11 | 12 | ;RUN: dsaopt %s -dsa-cbu -analyze -verify-flags "main:ptr-I+E" 13 | ;RUN: dsaopt %s -dsa-cbu -analyze -verify-flags "takesPointer:ptr+I-E" 14 | 15 | ;RUN: dsaopt %s -dsa-eq -analyze -verify-flags "main:ptr-I+E" 16 | ;RUN: dsaopt %s -dsa-eq -analyze -verify-flags "takesPointer:ptr+I-E" 17 | 18 | ;RUN: dsaopt %s -dsa-eqtd -analyze -verify-flags "main:ptr-I+E" 19 | ;RUN: dsaopt %s -dsa-eqtd -analyze -verify-flags "takesPointer:ptr-I+E" 20 | 21 | 22 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 23 | target triple = "x86_64-unknown-linux-gnu" 24 | 25 | define internal i32 @takesPointer(i32* nocapture %ptr) nounwind readonly { 26 | entry: 27 | %0 = load i32, i32* %ptr, align 4 ; [#uses=1] 28 | ret i32 %0 29 | } 30 | 31 | define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { 32 | entry: 33 | %ptr = tail call i32* (...) @getPointerExtern() nounwind 34 | %0 = tail call i32 @takesPointer(i32* %ptr) nounwind 35 | ret i32 %0 36 | } 37 | 38 | declare i32* @getPointerExtern(...) 39 | -------------------------------------------------------------------------------- /test/dsa/extern/extern_global2.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | static int * G = 0; 6 | 7 | typedef void (*fp)(int **); 8 | 9 | extern void external(fp f); 10 | 11 | static void C(int ** a) { 12 | // Make the argument point to the global. 13 | // Eventually, this link will make the global external because eventually, in TD, 14 | // our argument will be +E because we're externally callable. 15 | *a = G; 16 | } 17 | 18 | static void B(void) { 19 | // Pass something to C, doesn't really matter here. 20 | int a; 21 | int * ptr = &a; 22 | C(&ptr); 23 | } 24 | 25 | static void B2(void) { 26 | // This makes use of the global. 27 | // At somepoint, we should know that 'a' is external because 28 | // the global aliases the parameter and since C becomes externally callable 29 | int * a = G; 30 | int val = *a; 31 | } 32 | 33 | // Makes its argument external 34 | static void externalize(fp f) { 35 | external(f); 36 | } 37 | 38 | static void A(void) { 39 | // Here we make 'f' externally callable, but we don't know that 40 | // Until BU is run. 41 | fp f = C; 42 | externalize(f); 43 | 44 | // Call tree... 45 | B(); 46 | B2(); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /test/dsa/extern/extern_global_escape.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | #include 6 | 7 | int * globalptr = NULL; 8 | 9 | void externallyVisible(int * ptr) 10 | { 11 | globalptr = ptr; 12 | } 13 | 14 | void usesGlobalPtr() 15 | { 16 | int *ptr = globalptr; 17 | } 18 | 19 | int main() 20 | { 21 | int stack = 1; 22 | externallyVisible(&stack); 23 | usesGlobalPtr(); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/dsa/extern/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/local/array_of_struct.ll: -------------------------------------------------------------------------------- 1 | ; An example with an array of structs. The node for the array must 2 | ; be folded modulo the size of the struct element 3 | 4 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=test2:arr,0:i32::4:i32Array 5 | 6 | ; ModuleID = 'test2.bc' 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | %struct.sType = type { i32, i32 } 11 | 12 | define void @test2() nounwind { 13 | entry: 14 | %arr = alloca [10 x %struct.sType] ; <[10 x %struct.sType]*> [#uses=2] 15 | %z = alloca i32 ; [#uses=2] 16 | %t = alloca i32 ; [#uses=1] 17 | %t1 = alloca i32 ; [#uses=1] 18 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 19 | %0 = load i32, i32* %z, align 4 ; [#uses=1] 20 | %1 = sext i32 %0 to i64 ; [#uses=1] 21 | %2 = getelementptr inbounds [10 x %struct.sType], [10 x %struct.sType]* %arr, i64 0, i64 %1 ; <%struct.sType*> [#uses=1] 22 | %3 = getelementptr inbounds %struct.sType, %struct.sType* %2, i32 0, i32 1 ; [#uses=1] 23 | %4 = load i32, i32* %3, align 4 ; [#uses=1] 24 | store i32 %4, i32* %t, align 4 25 | %5 = load i32, i32* %z, align 4 ; [#uses=1] 26 | %6 = sext i32 %5 to i64 ; [#uses=1] 27 | %7 = getelementptr inbounds [10 x %struct.sType], [10 x %struct.sType]* %arr, i64 0, i64 %6 ; <%struct.sType*> [#uses=1] 28 | %8 = getelementptr inbounds %struct.sType, %struct.sType* %7, i32 0, i32 0 ; [#uses=1] 29 | %9 = load i32, i32* %8, align 4 ; [#uses=1] 30 | store i32 %9, i32* %t1, align 4 31 | br label %return 32 | 33 | return: ; preds = %entry 34 | ret void 35 | } 36 | -------------------------------------------------------------------------------- /test/dsa/local/arrays.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | //H, S, G, R, M 7 | 8 | #include 9 | 10 | void func() { 11 | 12 | int *arr = (int*) malloc(sizeof(int)*10); 13 | int i; 14 | for(i=0;i<10;i++) 15 | arr[i] = i; 16 | 17 | int *b = &arr[5]; 18 | int **c = &arr; 19 | int **d = &arr + 4; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/dsa/local/arrays1.c: -------------------------------------------------------------------------------- 1 | // Checks that structure field offsets are calculated correctly 2 | // Checks that structure is folded 3 | 4 | //--Make sure we can run DSA on it! 5 | //RUN: clang %s -c -emit-llvm -o - | \ 6 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 7 | 8 | #include 9 | 10 | struct StructType { 11 | 12 | int a; 13 | int *b; 14 | }; 15 | 16 | void func() { 17 | 18 | struct StructType *tmp = (struct StructType*) malloc(sizeof(struct StructType)*10); 19 | int i; 20 | for(i=0;i<10;i++) { 21 | tmp[i].a = i; 22 | tmp[i].b = &tmp[i].a; 23 | } 24 | 25 | struct StructType s2 = tmp[0]; 26 | int * c = s2.b; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /test/dsa/local/arrays2.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | //H, S, G, R, M 6 | 7 | #include 8 | 9 | struct StructType { 10 | 11 | int a; 12 | int *b; 13 | }; 14 | 15 | void func() { 16 | 17 | struct StructType *tmp = (struct StructType*) malloc(sizeof(struct StructType)*10); 18 | int i; 19 | for(i=0;i<10;i++) { 20 | tmp[i].a = i; 21 | } 22 | 23 | struct StructType s2 = tmp[0]; 24 | int * c = s2.b; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/dsa/local/arrays3.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | struct StructType { 9 | 10 | int a; 11 | int *b; 12 | }; 13 | 14 | void func() { 15 | 16 | struct StructType *tmp = (struct StructType*) malloc(sizeof(struct StructType)*10); 17 | int i; 18 | for(i=0;i<10;i++) { 19 | tmp[i].a = i; 20 | tmp[i].b = (int*) malloc(sizeof(int)); 21 | } 22 | 23 | struct StructType s2 = tmp[1]; 24 | int * c = s2.b; 25 | struct StructType *ptr = &s2; 26 | struct StructType *ptr1 = ptr + 1; 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/dsa/local/arrays4.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | //H, S, G, R, M 6 | 7 | #include 8 | 9 | struct StructType { 10 | 11 | int a; 12 | int *b; 13 | }; 14 | 15 | void func() { 16 | 17 | struct StructType tmp[10]; 18 | int i; 19 | for(i=0;i<10;i++) { 20 | tmp[i].a = i; 21 | } 22 | 23 | struct StructType s2 = tmp[0]; 24 | int * c = s2.b; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/dsa/local/bitfields1.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llvm-mirror/poolalloc/eb3a28cc226248240eb05273f543aca074979930/test/dsa/local/bitfields1.bc -------------------------------------------------------------------------------- /test/dsa/local/bitfields1.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | #include 6 | #include 7 | 8 | typedef union { 9 | struct { 10 | signed int immed:16; 11 | unsigned int rt:5; 12 | unsigned int rs:5; 13 | unsigned int rf:5; 14 | unsigned int opcode:6; 15 | }; 16 | unsigned int w; 17 | } I_format_t; 18 | 19 | 20 | int main() 21 | { 22 | I_format_t *ia = (I_format_t *)malloc(sizeof(I_format_t)); 23 | ia->w = 0xAFBE0010; 24 | printf("\ninstruction: %X\n",ia->w); 25 | printf("opcode: %X\n",ia->opcode); 26 | printf("rs: %d rt: %d rj: %d \n", ia->rs, ia->rt, ia->rf); 27 | printf("immed: %d\n",ia->immed); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /test/dsa/local/bitfields2.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | #include 6 | #include 7 | 8 | typedef union { 9 | struct { 10 | unsigned int fn:6; 11 | unsigned int sh:5; 12 | unsigned int rd:5; 13 | }; 14 | struct { 15 | signed int immed:16; 16 | unsigned int rt:5; 17 | unsigned int rs:5; 18 | unsigned int opcode:6; 19 | }; 20 | unsigned int w; 21 | } mips_format_t; 22 | 23 | 24 | int main() 25 | { 26 | int i; 27 | mips_format_t ia; 28 | unsigned int codes[] = {0x27bdffe8, 0xAFBE0010, 0x03A0F021, 0x2402000E}; 29 | int n = sizeof(codes)/sizeof(int); 30 | for (i=0; i 6 | 7 | struct taxonomy { 8 | unsigned kingdom: 2; 9 | unsigned phylum: 4; 10 | unsigned genus: 12; 11 | }; 12 | 13 | int main() 14 | { 15 | struct taxonomy t = {0, 0, 21}; 16 | t.kingdom = 1; 17 | t.phylum = 7; 18 | printf("sizeof(struct taxonomy): %d bytes\n",(int)sizeof(struct taxonomy)); 19 | printf("taxonomy: 0x%x\n",t); 20 | printf("kingdom: %d\n",t.kingdom); 21 | printf("phylum: %d\n",t.phylum); 22 | printf("genus: %d\n",t.genus); 23 | 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/dsa/local/flags.c: -------------------------------------------------------------------------------- 1 | // Go through at least one of every operation to verify flags are set appropriately... 2 | 3 | //--Make sure we can run DSA on it! 4 | //RUN: clang %s -c -emit-llvm -o - | \ 5 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 6 | 7 | //H, S, G, R, M 8 | 9 | #include 10 | 11 | //Not touched 12 | int global_a; 13 | //M 14 | int global_b; 15 | //R 16 | int global_c; 17 | //M/R 18 | int global_d; 19 | 20 | void func() { 21 | //Don't mod/ref 22 | int stack_a; 23 | //Mod 24 | int * heap_a = malloc(sizeof(int)); 25 | 26 | //Mod 27 | int stack_b; 28 | int * heap_b = malloc(sizeof(int)); 29 | 30 | //Ref 31 | int stack_c; 32 | int * heap_c = malloc(sizeof(int)); 33 | 34 | //Mod/Ref 35 | int stack_d; 36 | int * heap_d = malloc(sizeof(int)); 37 | 38 | //Mod the b's, ref the c's 39 | stack_b = stack_c; 40 | *heap_b = *heap_c; 41 | global_b = global_c; 42 | 43 | //Mod/ref all the d's 44 | stack_d = global_d; 45 | global_d = *heap_d; 46 | *heap_d = stack_d; 47 | 48 | free(heap_a); 49 | free(heap_b); 50 | free(heap_c); 51 | free(heap_d); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /test/dsa/local/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/local/malloc.ll: -------------------------------------------------------------------------------- 1 | ;--check that local detects call to malloc properly (marks them heap) 2 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "main:b:0+H" 3 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:b:0+IE" 4 | ;--check that local has b pointing to node containing c and d 5 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=main:b:0,main:c,main:d 6 | ;--check that td/bu don't mark such nodes as incomplete 7 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "main:c-I" 8 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "main:c-I" 9 | 10 | ; ModuleID = 'malloc_free.ll' 11 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 12 | target triple = "x86_64-unknown-linux-gnu" 13 | 14 | define i32 @main() nounwind { 15 | entry: 16 | %retval = alloca i32 ; [#uses=2] 17 | %a = alloca i32 ; [#uses=2] 18 | %b = alloca i8* ; [#uses=2] 19 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 20 | %c = call noalias i8* @malloc(i64 100) nounwind ; [#uses=1] 21 | store i8* %c, i8** %b, align 8 22 | %d = load i8*, i8** %b, align 8 ; [#uses=1] 23 | call void @free(i8* %d) nounwind 24 | store i32 0, i32* %a, align 4 25 | %e = load i32, i32* %a, align 4 ; [#uses=1] 26 | store i32 %e, i32* %retval, align 4 27 | br label %return 28 | 29 | return: ; preds = %entry 30 | %retval1 = load i32, i32* %retval ; [#uses=1] 31 | ret i32 %retval1 32 | } 33 | 34 | declare noalias i8* @malloc(i64) nounwind 35 | 36 | declare void @free(i8*) nounwind 37 | -------------------------------------------------------------------------------- /test/dsa/local/memcpy.ll: -------------------------------------------------------------------------------- 1 | ; RUN: dsaopt %s -dsa-local -analyze -check-same-node=test:P,test:Q 2 | ; RUN: llvm-as %s -o /dev/null 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | define void @test(i32* %P, i32* %Q) { 7 | entry: 8 | %tmp.1 = bitcast i32* %P to i8* ; [#uses=3] 9 | %tmp.3 = bitcast i32* %Q to i8* ; [#uses=4] 10 | tail call void @llvm.memcpy.p0i8.p0i8.i32( i8* %tmp.1, i8* %tmp.3, i32 100000, i32 0, i1 1 ) 11 | tail call void @llvm.memcpy.p0i8.p0i8.i64( i8* %tmp.1, i8* %tmp.3, i64 100000, i32 0, i1 1 ) 12 | tail call void @llvm.memset.p0i8.i32( i8* %tmp.3, i8 14, i32 10000, i32 0, i1 0 ) 13 | tail call void @llvm.memmove.p0i8.p0i8.i32( i8* %tmp.1, i8* %tmp.3, i32 123124, i32 0, i1 1 ) 14 | ret void 15 | } 16 | 17 | declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) 18 | 19 | declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) 20 | 21 | declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) 22 | 23 | declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) 24 | 25 | -------------------------------------------------------------------------------- /test/dsa/local/ptr.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | #include 6 | 7 | void func() { 8 | int a = 10; 9 | int *b = &a; 10 | int **c = &b; 11 | int *d = *c; 12 | int e = *d; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/dsa/local/ptr.ll: -------------------------------------------------------------------------------- 1 | 2 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:b:0,func:a,func:d:0 3 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:c:0,func:b 4 | 5 | 6 | ; ModuleID = 'ptr.bc' 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | define void @func() nounwind { 11 | entry: 12 | %a = alloca i32 ; [#uses=2] 13 | %b = alloca i32* ; [#uses=2] 14 | %c = alloca i32** ; [#uses=2] 15 | %d = alloca i32* ; [#uses=2] 16 | %e = alloca i32 ; [#uses=1] 17 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 18 | store i32 10, i32* %a, align 4 19 | store i32* %a, i32** %b, align 8 20 | store i32** %b, i32*** %c, align 8 21 | %0 = load i32**, i32*** %c, align 8 ; [#uses=1] 22 | %1 = load i32*, i32** %0, align 8 ; [#uses=1] 23 | store i32* %1, i32** %d, align 8 24 | %2 = load i32*, i32** %d, align 8 ; [#uses=1] 25 | %3 = load i32, i32* %2, align 4 ; [#uses=1] 26 | store i32 %3, i32* %e, align 4 27 | br label %return 28 | 29 | return: ; preds = %entry 30 | ret void 31 | } 32 | -------------------------------------------------------------------------------- /test/dsa/local/ptr1.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | #include 6 | 7 | void func() { 8 | int a = 10; 9 | int a1 = 20; 10 | int *b = &a; 11 | int *b1 = &a1; 12 | int **c; 13 | if( a > a1) { 14 | c = &b1; 15 | } else { 16 | c = &b; 17 | } 18 | int *d = *c; 19 | int e = *d; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/dsa/local/ptr1.ll: -------------------------------------------------------------------------------- 1 | 2 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:a,func:a1 3 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:a,func:b:0,func:b1:0,func:d:0 4 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:b,func:b1,func:c:0 5 | 6 | ; ModuleID = 'ptr1.bc' 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | define void @func() nounwind { 11 | entry: 12 | %a = alloca i32 ; [#uses=3] 13 | %a1 = alloca i32 ; [#uses=3] 14 | %b = alloca i32* ; [#uses=2] 15 | %b1 = alloca i32* ; [#uses=2] 16 | %c = alloca i32** ; [#uses=3] 17 | %d = alloca i32* ; [#uses=2] 18 | %e = alloca i32 ; [#uses=1] 19 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 20 | store i32 10, i32* %a, align 4 21 | store i32 20, i32* %a1, align 4 22 | store i32* %a, i32** %b, align 8 23 | store i32* %a1, i32** %b1, align 8 24 | %0 = load i32, i32* %a, align 4 ; [#uses=1] 25 | %1 = load i32, i32* %a1, align 4 ; [#uses=1] 26 | %2 = icmp sgt i32 %0, %1 ; [#uses=1] 27 | br i1 %2, label %bb, label %bb1 28 | 29 | bb: ; preds = %entry 30 | store i32** %b1, i32*** %c, align 8 31 | br label %bb2 32 | 33 | bb1: ; preds = %entry 34 | store i32** %b, i32*** %c, align 8 35 | br label %bb2 36 | 37 | bb2: ; preds = %bb1, %bb 38 | %3 = load i32**, i32*** %c, align 8 ; [#uses=1] 39 | %4 = load i32*, i32** %3, align 8 ; [#uses=1] 40 | store i32* %4, i32** %d, align 8 41 | %5 = load i32*, i32** %d, align 8 ; [#uses=1] 42 | %6 = load i32, i32* %5, align 4 ; [#uses=1] 43 | store i32 %6, i32* %e, align 4 44 | br label %return 45 | 46 | return: ; preds = %bb2 47 | ret void 48 | } 49 | -------------------------------------------------------------------------------- /test/dsa/local/ptr2.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | void func() { 9 | int a = 10; 10 | int a1 = 20; 11 | int *b = &a; 12 | int *b1 = &a1; 13 | int **c; 14 | if( a > a1) { 15 | c = &b1; 16 | } else { 17 | c = &b; 18 | } 19 | int *d = *c; 20 | int e = *d; 21 | int * f = d ; 22 | int ** g = c; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/dsa/local/struct.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | 9 | struct StructType { 10 | 11 | int a; 12 | int *b; 13 | }; 14 | 15 | void func() { 16 | 17 | int *tmp = (int*) malloc(sizeof(int)); 18 | struct StructType s1; 19 | s1.a = 10; 20 | s1.b = tmp; 21 | 22 | int *c = &s1.a; 23 | struct StructType s2 = s1; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /test/dsa/local/struct.ll: -------------------------------------------------------------------------------- 1 | 2 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:tmp:0,func:s2:8,func:s1:8 3 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=func:c:0,func:s1 4 | 5 | 6 | ; ModuleID = 'struct.bc' 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | %struct.StructType = type { i32, i32* } 11 | 12 | define void @func() nounwind { 13 | entry: 14 | %tmp = alloca i32* ; [#uses=2] 15 | %s1 = alloca %struct.StructType ; <%struct.StructType*> [#uses=5] 16 | %c = alloca i32* ; [#uses=1] 17 | %s2 = alloca %struct.StructType ; <%struct.StructType*> [#uses=2] 18 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 19 | %0 = call noalias i8* @malloc(i64 4) nounwind ; [#uses=1] 20 | %1 = bitcast i8* %0 to i32* ; [#uses=1] 21 | store i32* %1, i32** %tmp, align 8 22 | %2 = getelementptr inbounds %struct.StructType, %struct.StructType* %s1, i32 0, i32 0 ; [#uses=1] 23 | store i32 10, i32* %2, align 8 24 | %3 = getelementptr inbounds %struct.StructType, %struct.StructType* %s1, i32 0, i32 1 ; [#uses=1] 25 | %4 = load i32*, i32** %tmp, align 8 ; [#uses=1] 26 | store i32* %4, i32** %3, align 8 27 | %5 = getelementptr inbounds %struct.StructType, %struct.StructType* %s1, i32 0, i32 0 ; [#uses=1] 28 | store i32* %5, i32** %c, align 8 29 | %6 = getelementptr inbounds %struct.StructType, %struct.StructType* %s2, i32 0, i32 0 ; [#uses=1] 30 | %7 = getelementptr inbounds %struct.StructType, %struct.StructType* %s1, i32 0, i32 0 ; [#uses=1] 31 | %8 = load i32, i32* %7, align 8 ; [#uses=1] 32 | store i32 %8, i32* %6, align 8 33 | %9 = getelementptr inbounds %struct.StructType, %struct.StructType* %s2, i32 0, i32 1 ; [#uses=1] 34 | %10 = getelementptr inbounds %struct.StructType, %struct.StructType* %s1, i32 0, i32 1 ; [#uses=1] 35 | %11 = load i32*, i32** %10, align 8 ; [#uses=1] 36 | store i32* %11, i32** %9, align 8 37 | br label %return 38 | 39 | return: ; preds = %entry 40 | ret void 41 | } 42 | 43 | declare noalias i8* @malloc(i64) nounwind 44 | -------------------------------------------------------------------------------- /test/dsa/local/struct1.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | 9 | struct StructType { 10 | 11 | int a; 12 | int *b; 13 | }; 14 | 15 | void func() { 16 | 17 | int *tmp = (int*) malloc(sizeof(int)); 18 | struct StructType* s1 = (struct StructType*) malloc(sizeof(struct StructType)); 19 | s1->a = 10; 20 | s1->b = tmp; 21 | 22 | int *c = &(s1->a); 23 | struct StructType s2 = *s1; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /test/dsa/local/struct2.ll: -------------------------------------------------------------------------------- 1 | ; casting a struct to int 2 | 3 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=main:r,0:i64\|i32*::8:i32* 4 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=main:r:0,main:x 5 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:r+SUP2" 6 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:r1+SUP2" 7 | 8 | ; ModuleID = 'struct2.bc' 9 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 10 | target triple = "x86_64-unknown-linux-gnu" 11 | 12 | %struct.R = type { i32*, i32* } 13 | 14 | define i32 @main() nounwind { 15 | entry: 16 | %retval = alloca i32 ; [#uses=2] 17 | %0 = alloca i32 ; [#uses=2] 18 | %d = alloca i64 ; [#uses=1] 19 | %r = alloca %struct.R ; <%struct.R*> [#uses=3] 20 | %x = alloca i32 ; [#uses=1] 21 | %y = alloca i32 ; [#uses=1] 22 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 23 | %1 = getelementptr inbounds %struct.R, %struct.R* %r, i32 0, i32 0 ; [#uses=1] 24 | store i32* %x, i32** %1, align 8 25 | %2 = getelementptr inbounds %struct.R, %struct.R* %r, i32 0, i32 1 ; [#uses=1] 26 | store i32* %y, i32** %2, align 8 27 | %r1 = bitcast %struct.R* %r to i64* ; [#uses=1] 28 | %3 = load i64, i64* %r1, align 8 ; [#uses=1] 29 | store i64 %3, i64* %d, align 8 30 | store i32 0, i32* %0, align 4 31 | %4 = load i32, i32* %0, align 4 ; [#uses=1] 32 | store i32 %4, i32* %retval, align 4 33 | br label %return 34 | 35 | return: ; preds = %entry 36 | %retval3 = load i32, i32* %retval ; [#uses=1] 37 | ret i32 %retval3 38 | } 39 | -------------------------------------------------------------------------------- /test/dsa/local/struct4.ll: -------------------------------------------------------------------------------- 1 | ;accessing 1st field using struct pointer 2 | 3 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=main:r,0:i32*::8:i32*::16:i8* 4 | 5 | ; ModuleID = 'struct4.o' 6 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 7 | target triple = "x86_64-unknown-linux-gnu" 8 | 9 | %struct.R = type { i32*, i32*, i8* } 10 | 11 | define i32 @main() nounwind { 12 | entry: 13 | %retval = alloca i32 ; [#uses=2] 14 | %0 = alloca i32 ; [#uses=2] 15 | %r = alloca %struct.R ; <%struct.R*> [#uses=4] 16 | %x = alloca i32 ; [#uses=2] 17 | %y = alloca i32 ; [#uses=1] 18 | %c = alloca i8 ; [#uses=1] 19 | %p = alloca i32** ; [#uses=2] 20 | %d = alloca i32 ; [#uses=1] 21 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 22 | store i32 5, i32* %x, align 4 23 | %1 = getelementptr inbounds %struct.R, %struct.R* %r, i32 0, i32 0 ; [#uses=1] 24 | store i32* %x, i32** %1, align 8 25 | %2 = getelementptr inbounds %struct.R, %struct.R* %r, i32 0, i32 1 ; [#uses=1] 26 | store i32* %y, i32** %2, align 8 27 | %3 = getelementptr inbounds %struct.R, %struct.R* %r, i32 0, i32 2 ; [#uses=1] 28 | store i8* %c, i8** %3, align 8 29 | %r1 = bitcast %struct.R* %r to i32** ; [#uses=1] 30 | store i32** %r1, i32*** %p, align 8 31 | %4 = load i32**, i32*** %p, align 8 ; [#uses=1] 32 | %5 = load i32*, i32** %4, align 8 ; [#uses=1] 33 | %6 = load i32, i32* %5, align 4 ; [#uses=1] 34 | store i32 %6, i32* %d, align 4 35 | store i32 0, i32* %0, align 4 36 | %7 = load i32, i32* %0, align 4 ; [#uses=1] 37 | store i32 %7, i32* %retval, align 4 38 | br label %return 39 | 40 | return: ; preds = %entry 41 | %retval2 = load i32, i32* %retval ; [#uses=1] 42 | ret i32 %retval2 43 | } 44 | -------------------------------------------------------------------------------- /test/dsa/local/struct_malloc.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=func:struct,0:i32::4:i32 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | declare noalias i8* @malloc(i64) nounwind 6 | 7 | define void @func() nounwind { 8 | entry: 9 | ; Allocate 2 x i32 = 8 bytes 10 | %struct = call noalias i8* @malloc(i64 8) nounwind 11 | 12 | ; Index into first, store 0 there 13 | %ptr = getelementptr inbounds i8, i8* %struct, i64 0 14 | %conv = bitcast i8* %ptr to i32* 15 | store i32 0, i32* %conv, align 4 16 | 17 | ; Index into second, store 0 there also 18 | %ptr2 = getelementptr inbounds i8, i8* %struct, i64 4 19 | %conv2 = bitcast i8* %ptr2 to i32* 20 | store i32 0, i32* %conv2, align 4 21 | ret void 22 | } 23 | -------------------------------------------------------------------------------- /test/dsa/local/union_P2I.ll: -------------------------------------------------------------------------------- 1 | ;checks that the PtrToInt and IntToPtr flag is set on unions that contain integer and pointer types 2 | 3 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=main:ptr:0,main:obj:0 4 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=main:obj,FoldedVOID 5 | ;RUN: adsaopt %s -simplify-gep -mergearrgep -o t.bc 6 | ;RUN: dsaopt t.bc -dsa-local -enable-type-inference-opts -analyze -check-type=main:obj,0:i32\|\[100x%\struct.StructType\] 7 | 8 | 9 | ; ModuleID = 'union_P2.bc' 10 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 11 | target triple = "x86_64-unknown-linux-gnu" 12 | 13 | %struct.StructType = type { %struct.StructType*, double } 14 | %union.UnionType = type { [100 x %struct.StructType] } 15 | 16 | define i32 @main() nounwind { 17 | entry: 18 | %retval = alloca i32 ; [#uses=1] 19 | %obj = alloca %union.UnionType ; <%union.UnionType*> [#uses=2] 20 | %ptr = alloca %struct.StructType* ; <%struct.StructType**> [#uses=1] 21 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 22 | %0 = getelementptr inbounds %union.UnionType, %union.UnionType* %obj, i32 0, i32 0 ; <[100 x %struct.StructType]*> [#uses=1] 23 | %1 = bitcast [100 x %struct.StructType]* %0 to i32* ; [#uses=1] 24 | store i32 123456, i32* %1, align 8 25 | %2 = getelementptr inbounds %union.UnionType, %union.UnionType* %obj, i32 0, i32 0 ; <[100 x %struct.StructType]*> [#uses=1] 26 | %3 = getelementptr inbounds [100 x %struct.StructType], [100 x %struct.StructType]* %2, i64 0, i64 0 ; <%struct.StructType*> [#uses=1] 27 | %4 = getelementptr inbounds %struct.StructType, %struct.StructType* %3, i32 0, i32 0 ; <%struct.StructType**> [#uses=1] 28 | %5 = load %struct.StructType*, %struct.StructType** %4, align 8 ; <%struct.StructType*> [#uses=1] 29 | store %struct.StructType* %5, %struct.StructType** %ptr, align 8 30 | br label %return 31 | 32 | return: ; preds = %entry 33 | %retval1 = load i32, i32* %retval ; [#uses=1] 34 | ret i32 %retval1 35 | } 36 | -------------------------------------------------------------------------------- /test/dsa/local/union_P2I_1.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=main:c:0,main:obj:0 2 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=main:obj,FoldedVOID 3 | 4 | ;union of array of int/int*. Must get collapsed, as the element type is not of consistent size 5 | 6 | ; ModuleID = 'union_P2I_1.bc' 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | %union.UnionType = type { [100 x i32*] } 11 | 12 | define i32 @main() nounwind { 13 | entry: 14 | %retval = alloca i32 ; [#uses=1] 15 | %obj = alloca %union.UnionType ; <%union.UnionType*> [#uses=2] 16 | %c = alloca i32* ; [#uses=1] 17 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 18 | %0 = getelementptr inbounds %union.UnionType, %union.UnionType* %obj, i32 0, i32 0 ; <[100 x i32*]*> [#uses=1] 19 | %1 = bitcast [100 x i32*]* %0 to [100 x i32]* ; <[100 x i32]*> [#uses=1] 20 | %2 = getelementptr inbounds [100 x i32], [100 x i32]* %1, i64 0, i64 3 ; [#uses=1] 21 | store i32 123456, i32* %2, align 4 22 | %3 = getelementptr inbounds %union.UnionType, %union.UnionType* %obj, i32 0, i32 0 ; <[100 x i32*]*> [#uses=1] 23 | %4 = getelementptr inbounds [100 x i32*], [100 x i32*]* %3, i64 0, i64 3 ; [#uses=1] 24 | %5 = load i32*, i32** %4, align 8 ; [#uses=1] 25 | store i32* %5, i32** %c, align 8 26 | br label %return 27 | 28 | return: ; preds = %entry 29 | %retval1 = load i32, i32* %retval ; [#uses=1] 30 | ret i32 %retval1 31 | } 32 | -------------------------------------------------------------------------------- /test/dsa/regression/2010-07-08.FPDeclaration.c: -------------------------------------------------------------------------------- 1 | //Test that DSA doesn't crash when processing an indirect call to an external function. 2 | //RUN: clang -S -emit-llvm -c %s -o %t.bc 3 | //RUN: dsaopt %t.bc -dsa-td -disable-output 4 | 5 | extern void func(void); 6 | 7 | int main() { 8 | void (*fp)(void) = func; 9 | fp(); 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /test/dsa/regression/2010-07-09-vastartUndef.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-local -disable-output 2 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | declare void @llvm.va_start(i8*) nounwind 7 | 8 | define void @test() { 9 | call void @llvm.va_start(i8* undef) 10 | ret void 11 | } 12 | -------------------------------------------------------------------------------- /test/dsa/regression/2010-08-17-VarArgSize.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = '2010-08-17-VarArgSize.ll' 2 | ;RUN: dsaopt %s -dsa-bu 3 | target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" 4 | target triple = "i386-pc-linux-gnu" 5 | 6 | declare void @llvm.va_start(i8*) nounwind 7 | 8 | define void @func(i32 %unused, i8* nocapture %fmt, ...) nounwind { 9 | entry: 10 | %ap = bitcast i8** undef to i8* 11 | call void @llvm.va_start(i8* %ap) 12 | call void @llvm.va_start(i8* %ap) 13 | ret void 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /test/dsa/regression/2011-03-17-CBUAssert.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-cbu -disable-output 2 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | %struct.anon = type { %struct.node*, %struct.node* } 7 | %struct.bitvect_t = type { i32*, i32, i32 } 8 | %struct.node = type { i32, %union.anon, %struct.bitvect_t*, %struct.bitvect_t*, i32 } 9 | %struct.regmatcher = type { [128 x i32], i32, i32**, i32* } 10 | %union.anon = type { %struct.anon } 11 | 12 | define %struct.regmatcher* @compile(i8* %expr) nounwind { 13 | entry: 14 | %0 = call %struct.node* (...) bitcast (%struct.node* ()* @end_node to %struct.node* (...)*)() nounwind ; <%struct.node*> [#uses=0] 15 | unreachable 16 | } 17 | 18 | define %struct.node* @end_node() nounwind { 19 | entry: 20 | ret %struct.node* undef 21 | } 22 | 23 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-04-29.GlobalInitCollapse.ll: -------------------------------------------------------------------------------- 1 | ; Global initializers cause node for global to collapse before processing it 2 | ; Reduced in spirit from 403.gcc 3 | ;RUN: dsaopt %s -dsa-local -disable-output 4 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5 | target triple = "x86_64-unknown-linux-gnu" 6 | 7 | %struct.IntPair = type { i32, i32 } 8 | 9 | @ptr = global i8* getelementptr (i8, i8* bitcast (i32* getelementptr inbounds (%struct.IntPair, %struct.IntPair* @ip, i64 0, i32 1) to i8*), i64 2), align 8 10 | @ip = global %struct.IntPair { i32 5, i32 10 }, align 4 11 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-04-29.SQLiteBUInfiniteRecursion.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-bu -disable-output 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | define internal i32* @func(i32* %arg) nounwind { 6 | entry: 7 | %0 = call i32* @A() nounwind 8 | ret i32* %0 9 | } 10 | 11 | define internal i32* @C(i32* (i32*)* %f, i32* %arg) nounwind { 12 | entry: 13 | %0 = call i32* @A() nounwind 14 | %1 = call i32* @B() nounwind 15 | %2 = call i32* @func(i32* %1) nounwind 16 | %3 = call i32* %f(i32* %arg) nounwind 17 | ret i32* %3 18 | } 19 | 20 | define internal i32* @B() nounwind { 21 | entry: 22 | %0 = call i32* @A() nounwind 23 | %1 = call i32* @C(i32* (i32*)* @func, i32* %0) nounwind 24 | ret i32* %1 25 | } 26 | 27 | define internal i32* @A() nounwind { 28 | entry: 29 | %0 = call i32* @B() nounwind 30 | %1 = call i32* @func(i32* %0) nounwind 31 | ret i32* %1 32 | } 33 | 34 | define internal i32* @D() nounwind { 35 | entry: 36 | %0 = call i32* @A() nounwind 37 | ret i32* %0 38 | } 39 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-04-29.StructOOBIndex.ll: -------------------------------------------------------------------------------- 1 | ; OOB indexing example reduced from 483.xalancbmk 2 | ;RUN: dsaopt %s -dsa-local -disable-output 3 | ;RUN: dsaopt %s -dsa-bu -disable-output 4 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5 | target triple = "x86_64-unknown-linux-gnu" 6 | 7 | %structType = type { i32, i8*, i32 } 8 | 9 | ; Index OOB in a single function 10 | define i32 @foo(%structType* %t) { 11 | ; Treat 't' as an array of structs, and index to the 'i8*' in the second one 12 | %ptr = getelementptr inbounds %structType, %structType* %t, i64 1, i32 1 13 | ; Cast so indexing past end of struct is 'allowed' 14 | %cast = bitcast i8** %ptr to %structType* 15 | ; Get pointer to second 'i32' that's now OOB of the original struct type 16 | %ptr2 = getelementptr inbounds %structType, %structType* %cast, i32 0, i32 2 17 | ret i32 0 18 | } 19 | 20 | ; Same thing, only split across two functions 21 | define i32 @fooStart(%structType* %t) { 22 | ; Treat 't' as an array of structs, and index to the 'i8*' in the second one 23 | %ptr = getelementptr inbounds %structType, %structType* %t, i64 1, i32 1 24 | ; Cast so indexing past end of struct is 'allowed' 25 | %cast = bitcast i8** %ptr to %structType* 26 | ; Call other function to finish 27 | %val = tail call i32 @fooGEP(%structType* %cast) 28 | ret i32 %val 29 | } 30 | 31 | declare void @fooEmpty(i32* %val) 32 | 33 | define i32 @fooGEP(%structType* %t) { 34 | ; Get pointer to second 'i32' that's now OOB of the original struct type 35 | %ptr = getelementptr inbounds %structType, %structType* %t, i32 0, i32 2 36 | ; Use in call, triggers similar bug in inlining calls 37 | call void @fooEmpty(i32* %ptr) 38 | ret i32 0 39 | } 40 | 41 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-05-05.GlobalCtorsDecl.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-bu -disable-output 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | @llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] 6 | 7 | declare void @_GLOBAL__I_a() nounwind 8 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-05-05.GlobalCtorsSCC.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-eq -disable-output 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | @llvm.global_ctors = appending global [3 x { i32, void ()* }] 6 | [{ i32, void ()* } { i32 0, void ()* @A }, 7 | { i32, void ()* } { i32 0, void ()* @B }, 8 | { i32, void ()* } { i32 0, void ()* @C }] 9 | 10 | declare void @A() nounwind 11 | define void @B() { 12 | call void @C() 13 | ret void 14 | } 15 | define void @C() { 16 | call void @B() 17 | ret void 18 | } 19 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-05-05.PtrToIntInfiniteLoop.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-local -disable-output 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | define void @A() { 6 | entry: 7 | %0 = alloca i32 8 | %1 = ptrtoint i32* %0 to i64 9 | br label %loop 10 | 11 | loop: 12 | %2 = phi i64 [ %1, %entry ], [ %2, %loop ] 13 | br label %loop 14 | 15 | ret: 16 | ret void 17 | } 18 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-09-27.ConstantAggregate.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-eq -disable-output 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | define void @test() nounwind { 6 | entry: 7 | %ptr = alloca i32 8 | %ptr2 = alloca i32 9 | ; Handle insertvalue on constantstruct 10 | %struct = insertvalue {i64, i32*} { i64 10, i32* null }, i32 *%ptr, 1 11 | %struct2 = insertvalue {i64, i32*} %struct, i32 *%ptr2, 1 12 | ; Load the pointer (unification says may be ptr or ptr2), 13 | ; and verify we tracked it properly: 14 | ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=test:ptr,test:ptr2,test:both 15 | %both = extractvalue {i64, i32*} %struct, 1 16 | ; Ensure handle extractvalue on constantstruct also 17 | %val = extractvalue {i64, i64} { i64 10, i64 5 }, 1 18 | 19 | ret void 20 | } 21 | 22 | ; While we're at it, verify we don't die on similar constructs 23 | ; when accessing (constant) arrays/vectors. 24 | define void @ArrayAndVector() nounwind { 25 | entry: 26 | %0 = extractvalue [2 x i64] [i64 10, i64 20], 1 27 | %1 = insertvalue [2 x i64] [i64 10, i64 20], i64 %0, 1 28 | %2 = extractelement <2 x i64> , i32 1 29 | %3 = insertelement <2 x i64> , i64 %2, i32 1 30 | ret void 31 | } 32 | -------------------------------------------------------------------------------- /test/dsa/regression/2012-11-19.ExternFuncSummaries.ll: -------------------------------------------------------------------------------- 1 | ; PR12786 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | declare i8* @getcwd(i8*) nounwind 6 | 7 | ; Result of getcwd should be merged with its argument 8 | ; RUN: dsaopt %s -dsa-stdlib -analyze -check-same-node=test_cwd:ret,test_cwd:arg 9 | define i8* @test_cwd(i8* %arg) nounwind { 10 | %ret = call i8* @getcwd(i8* %arg) nounwind 11 | ret i8* %ret 12 | } 13 | 14 | declare i8* @strstr(i8*,i8*) nounwind 15 | 16 | ; Result of strstr should be merged with its first argument, second should be separate 17 | ; RUN: dsaopt %s -dsa-stdlib -analyze -check-same-node=test_strstr:ret,test_strstr:arg1 18 | ; RUN: dsaopt %s -dsa-stdlib -analyze -check-not-same-node=test_strstr:ret,test_strstr:arg2 19 | ; RUN: dsaopt %s -dsa-stdlib -analyze -check-not-same-node=test_strstr:arg1,test_strstr:arg2 20 | define i8* @test_strstr(i8* %arg1, i8* %arg2) nounwind { 21 | %ret = call i8* @strstr(i8* %arg1, i8* %arg2) nounwind 22 | ret i8* %ret 23 | } 24 | -------------------------------------------------------------------------------- /test/dsa/regression/2014-05-06.PR19175-CollapseVA.ll: -------------------------------------------------------------------------------- 1 | ; RUN: dsaopt %s -dsa-local -disable-output 2 | ; (Reduced testcase from submitted file demonstrating assertion failure) 3 | ; PR19175 4 | ; "Assert fails because a node collapse while handling a Vararg within structure on LocalDataStructure Analysis" 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | %struct.__va_list_tag.0.2.16 = type { i32, i32, i8*, i8* } 9 | %struct.t.1.3.17 = type { [1 x %struct.__va_list_tag.0.2.16], i8* } 10 | 11 | ; Function Attrs: nounwind 12 | declare void @llvm.va_start(i8*) #0 13 | 14 | ; Function Attrs: nounwind uwtable 15 | define void @test_va_bugging_func(i32 %p1, ...) #1 { 16 | entry: 17 | %v = getelementptr inbounds %struct.t.1.3.17, %struct.t.1.3.17* undef, i32 0, i32 0 18 | %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag.0.2.16], [1 x %struct.__va_list_tag.0.2.16]* %v, i32 0, i32 0 19 | %arraydecay1 = bitcast %struct.__va_list_tag.0.2.16* %arraydecay to i8* 20 | call void @llvm.va_start(i8* %arraydecay1) 21 | unreachable 22 | } 23 | 24 | attributes #0 = { nounwind } 25 | attributes #1 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 26 | -------------------------------------------------------------------------------- /test/dsa/regression/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/td/ExternFuncNodeTest1.ll: -------------------------------------------------------------------------------- 1 | ; Example in which we take address of an external function 2 | ; make sure that it is marked X(externFuncNode). 3 | ; and that it is not inlined 4 | ; Checking that the X flag is propogated everywhere. 5 | 6 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "@fp:0+EX" 7 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "@fp:0+EX" 8 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "@fp:0+EX" 9 | ;RUN: dsaopt %s -dsa-cbu -analyze -verify-flags "@fp:0+EX" 10 | ;RUN: dsaopt %s -dsa-eq -analyze -verify-flags "@fp:0+EX" 11 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "@fp:0+EX" 12 | ;RUN: dsaopt %s -dsa-eqtd -analyze -verify-flags "@fp:0+EX" 13 | 14 | ; ModuleID = 'fn.o' 15 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 16 | target triple = "x86_64-unknown-linux-gnu" 17 | 18 | @fp = global i8* (i32)* bitcast (i8* (i64)* @malloc to i8* (i32)*) ; [#uses=1] 19 | 20 | declare noalias i8* @malloc(i64) nounwind 21 | 22 | define void @main() nounwind { 23 | entry: 24 | %0 = load i8* (i32)*, i8* (i32)** @fp, align 8 ; [#uses=1] 25 | %1 = call i8* %0(i32 32) nounwind ; [#uses=0] 26 | br label %return 27 | 28 | return: ; preds = %entry 29 | ret void 30 | } 31 | -------------------------------------------------------------------------------- /test/dsa/td/ExternFuncNodeTest2.ll: -------------------------------------------------------------------------------- 1 | ; Example in which we take address of an external function 2 | ; make sure that it is marked X(externFuncNode). 3 | ; and that it is not inlined 4 | ; Checking that the X flag is propogated everywhere. 5 | 6 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "@fp:0+X" 7 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "@fp:0+X" 8 | ;RUN: dsaopt %s -dsa-cbu -analyze -verify-flags "@fp:0+X" 9 | ;RUN: dsaopt %s -dsa-eq -analyze -verify-flags "@fp:0+X" 10 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "@fp:0+X" 11 | ;RUN: dsaopt %s -dsa-eqtd -analyze -verify-flags "@fp:0+X" 12 | 13 | ; ModuleID = 'ttt' 14 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 15 | target triple = "x86_64-unknown-linux-gnu" 16 | 17 | @fp = internal global i8* (i32)* bitcast (i8* (i64)* @malloc to i8* (i32)*) ; [#uses=1] 18 | 19 | declare noalias i8* @malloc(i64) nounwind 20 | 21 | define internal void @init() nounwind { 22 | entry: 23 | %0 = load i8* (i32)*, i8* (i32)** @fp, align 8 ; [#uses=1] 24 | %1 = call i8* %0(i32 32) nounwind ; [#uses=0] 25 | br label %return 26 | 27 | return: ; preds = %entry 28 | ret void 29 | } 30 | 31 | define void @main() nounwind { 32 | entry: 33 | call void @init() nounwind 34 | br label %return 35 | 36 | return: ; preds = %entry 37 | ret void 38 | } 39 | -------------------------------------------------------------------------------- /test/dsa/td/call.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | 9 | static int* test() { 10 | int* a2 = (int*)malloc(sizeof(int)); 11 | *a2 = 10; 12 | 13 | if(*a2 > 5 ) { 14 | return a2; 15 | } 16 | 17 | int *b2 = (int*)malloc(sizeof(int)); 18 | return b2; 19 | 20 | } 21 | 22 | void func() { 23 | 24 | int *a1 = test(); 25 | int *b1 = test(); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/dsa/td/call1.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | int* test(int **a2, int **b2) { 9 | int *temp; 10 | temp = *a2; 11 | a2 = b2; 12 | *b2 = temp; 13 | 14 | return *a2; 15 | } 16 | 17 | void func() { 18 | 19 | int* mem1 = (int *)malloc(sizeof(int)); 20 | int* mem2 = (int *)malloc(sizeof(int)); 21 | int *a1 = test(&mem1, &mem2); 22 | int *b1 = test(&mem2, &mem1); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/dsa/td/call2.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | int* test(int **a2, int **b2) { 9 | int *temp; 10 | temp = *a2; 11 | a2 = b2; 12 | *b2 = temp; 13 | 14 | return *a2; 15 | } 16 | 17 | void func() { 18 | 19 | int* mem1 = (int *)malloc(sizeof(int)); 20 | int* mem2 = (int *)malloc(sizeof(int)); 21 | int *a1 = test(&mem1, &mem2); 22 | int *b1 = test(&mem1, &mem2); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/dsa/td/chain.ll: -------------------------------------------------------------------------------- 1 | ; Verify callgraph is as expected for all DSA passes 2 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=A,B 3 | ;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=B,C 4 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=A,B 5 | ;RUN: dsaopt %s -dsa-bu -analyze -check-callees=B,C 6 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=A,B 7 | ;RUN: dsaopt %s -dsa-td -analyze -check-callees=B,C 8 | 9 | ; Verify the heap flag is also set appropriately where it should be 10 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "C:memC-H" 11 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "B:memB-H" 12 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "A:memA-H" 13 | 14 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "C:memC+H" 15 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "B:memB-H" 16 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "A:memA-H" 17 | 18 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "C:memC+H" 19 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "B:memB+H" 20 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "A:memA+H" 21 | 22 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "C:memC+H" 23 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "B:memB+H" 24 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "A:memA+H" 25 | 26 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 27 | target triple = "x86_64-unknown-linux-gnu" 28 | 29 | declare noalias i8* @malloc(i64) nounwind 30 | 31 | ; Malloc wrapper 32 | define i8* @C(i64 %size) { 33 | entry: 34 | %memC = call noalias i8* @malloc(i64 %size) nounwind 35 | store i8 5, i8* %memC, align 8 ; Store so this isn't detected as an allocator 36 | ret i8* %memC 37 | } 38 | 39 | ; Chain along to malloc wrapper 40 | define i8* @B() { 41 | entry: 42 | %memB = call i8* @C(i64 10) 43 | ret i8* %memB 44 | } 45 | 46 | define void @A() { 47 | entry: 48 | %memA = call i8* @B() 49 | ;call void free(i8* %memA) 50 | ; (leak) 51 | ret void 52 | } 53 | -------------------------------------------------------------------------------- /test/dsa/td/checkIncomplete.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "print:buffer+I" 2 | ;RUN: dsaopt %s -dsa-stdlib -analyze -verify-flags "@buf-I" 3 | 4 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "print:buffer+I" 5 | ;RUN: dsaopt %s -dsa-bu -analyze -verify-flags "@buf-I" 6 | 7 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "print:buffer-I" 8 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "@buf-I" 9 | 10 | ; global buf, is passed as argument to print. It should not be marked incomplete after td 11 | 12 | ; ModuleID = 'checkIncomplete.o' 13 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 14 | target triple = "x86_64-unknown-linux-gnu" 15 | 16 | @buf = internal global [30 x i8] zeroinitializer, align 16 ; <[30 x i8]*> [#uses=1] 17 | 18 | define internal void @print(i8* %buffer) nounwind { 19 | entry: 20 | %buffer_addr = alloca i8* ; [#uses=2] 21 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 22 | store i8* %buffer, i8** %buffer_addr 23 | %0 = load i8*, i8** %buffer_addr, align 8 ; [#uses=1] 24 | %1 = getelementptr inbounds i8, i8* %0, i64 0 ; [#uses=1] 25 | store i8 97, i8* %1, align 1 26 | br label %return 27 | 28 | return: ; preds = %entry 29 | ret void 30 | } 31 | 32 | define void @main() nounwind { 33 | entry: 34 | call void @print(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @buf, i64 0, i64 0)) nounwind 35 | br label %return 36 | 37 | return: ; preds = %entry 38 | ret void 39 | } 40 | -------------------------------------------------------------------------------- /test/dsa/td/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/td/mergeArgs.ll: -------------------------------------------------------------------------------- 1 | ; Pass same pointer(from main) as 2 different args to func 2 | ; The formal args to func do not alias in func 3 | ; Verify that the node is merged in TD 4 | 5 | ;RUN: dsaopt %s -dsa-td -analyze -check-same-node=func:arg1,func:arg2 6 | ;RUN: dsaopt %s -dsa-bu -analyze -check-not-same-node=func:arg1,func:arg2 7 | 8 | ; ModuleID = 'mergeArgs.o' 9 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 10 | target triple = "x86_64-unknown-linux-gnu" 11 | 12 | define void @func(i32* %arg1, i32* %arg2) nounwind { 13 | entry: 14 | %arg1_addr = alloca i32* ; [#uses=2] 15 | %arg2_addr = alloca i32* ; [#uses=2] 16 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 17 | store i32* %arg1, i32** %arg1_addr 18 | store i32* %arg2, i32** %arg2_addr 19 | %0 = load i32*, i32** %arg1_addr, align 8 ; [#uses=1] 20 | store i32 1, i32* %0, align 4 21 | %1 = load i32*, i32** %arg2_addr, align 8 ; [#uses=1] 22 | store i32 2, i32* %1, align 4 23 | br label %return 24 | 25 | return: ; preds = %entry 26 | ret void 27 | } 28 | 29 | define i32 @main() nounwind { 30 | entry: 31 | %retval = alloca i32 ; [#uses=1] 32 | %p = alloca i32* ; [#uses=3] 33 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 34 | %0 = call noalias i8* @malloc(i64 4) nounwind ; [#uses=1] 35 | %1 = bitcast i8* %0 to i32* ; [#uses=1] 36 | store i32* %1, i32** %p, align 8 37 | %2 = load i32*, i32** %p, align 8 ; [#uses=1] 38 | %3 = load i32*, i32** %p, align 8 ; [#uses=1] 39 | call void @func(i32* %2, i32* %3) nounwind 40 | br label %return 41 | 42 | return: ; preds = %entry 43 | %retval1 = load i32, i32* %retval ; [#uses=1] 44 | ret i32 %retval1 45 | } 46 | 47 | declare noalias i8* @malloc(i64) nounwind 48 | -------------------------------------------------------------------------------- /test/dsa/td/mergeArgs1.ll: -------------------------------------------------------------------------------- 1 | ; Pass same pointer(from main) as 2 different args to func 2 | ; The formal args to func do not alias in func 3 | ; Verify that the node is merged in TD 4 | 5 | ;RUN: dsaopt %s -dsa-td -analyze -check-same-node=func:arg1:0,func:arg2 6 | ;RUN: dsaopt %s -dsa-bu -analyze -check-not-same-node=func:arg1:0,func:arg2 7 | 8 | ; ModuleID = 'mergeArgs.o' 9 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 10 | target triple = "x86_64-unknown-linux-gnu" 11 | 12 | define void @func(i32** %arg1, i32* %arg2) nounwind { 13 | entry: 14 | %arg1_addr = alloca i32** ; [#uses=2] 15 | %arg2_addr = alloca i32* ; [#uses=2] 16 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 17 | store i32** %arg1, i32*** %arg1_addr 18 | store i32* %arg2, i32** %arg2_addr 19 | %0 = load i32**, i32*** %arg1_addr, align 8 ; [#uses=1] 20 | %1 = load i32*, i32** %0, align 8 ; [#uses=1] 21 | store i32 1, i32* %1, align 4 22 | %2 = load i32*, i32** %arg2_addr, align 8 ; [#uses=1] 23 | store i32 2, i32* %2, align 4 24 | br label %return 25 | 26 | return: ; preds = %entry 27 | ret void 28 | } 29 | 30 | define i32 @main() nounwind { 31 | entry: 32 | %retval = alloca i32 ; [#uses=1] 33 | %p = alloca i32* ; [#uses=3] 34 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 35 | %0 = call noalias i8* @malloc(i64 4) nounwind ; [#uses=1] 36 | %1 = bitcast i8* %0 to i32* ; [#uses=1] 37 | store i32* %1, i32** %p, align 8 38 | %2 = load i32*, i32** %p, align 8 ; [#uses=1] 39 | call void @func(i32** %p, i32* %2) nounwind 40 | br label %return 41 | 42 | return: ; preds = %entry 43 | %retval1 = load i32, i32* %retval ; [#uses=1] 44 | ret i32 %retval1 45 | } 46 | 47 | declare noalias i8* @malloc(i64) nounwind 48 | -------------------------------------------------------------------------------- /test/dsa/td/params.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | int* test(int **a2, int **b2) { 9 | int *temp = *a2; 10 | int *temp1 = *b2; 11 | if(*temp1 < *temp) { 12 | return *b2; 13 | } 14 | else { 15 | int *temp2 = (int*)malloc(sizeof(int)); 16 | a2 = &temp2; 17 | } 18 | 19 | return *a2; 20 | } 21 | 22 | void func() { 23 | 24 | int* mem1; 25 | int* mem2; 26 | int r1 = 5; 27 | int r2 = 6; 28 | mem1 = &r1; 29 | mem2 = &r2; 30 | int *a1 = test(&mem1, &mem2); 31 | int *b1 = test(&mem2, &mem1); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /test/dsa/td/params1.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | struct InfoStruct { 9 | int count; 10 | int valid; 11 | float factor; 12 | }; 13 | 14 | void initialize(struct InfoStruct **arr, int size) { 15 | struct InfoStruct *temp = *arr; 16 | while(temp < (*arr + size)) { 17 | temp->count = 0; 18 | temp->valid = 0; 19 | temp->factor = 0.0; 20 | temp++; 21 | } 22 | } 23 | 24 | void process(struct InfoStruct **arr, int loc, int count, float fact) { 25 | 26 | struct InfoStruct *ptr = *arr; 27 | struct InfoStruct obj; 28 | obj.count = count; 29 | obj.factor = fact; 30 | obj.valid = 1; 31 | ptr[loc]=obj; 32 | } 33 | 34 | int main() { 35 | 36 | struct InfoStruct* InfoArray= (struct InfoStruct*)malloc(sizeof(struct InfoStruct) * 10); 37 | initialize(&InfoArray, 10); 38 | process(&InfoArray, 4, 3, 5.5); 39 | } 40 | -------------------------------------------------------------------------------- /test/dsa/td/recur.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | 9 | int* test() { 10 | int* a2 = (int*)malloc(sizeof(int)); 11 | *a2 = 10; 12 | 13 | if(*a2 > 5 ) { 14 | return test(); 15 | } 16 | 17 | int *b2 = (int*)malloc(sizeof(int)); 18 | return b2; 19 | 20 | } 21 | 22 | void func() { 23 | 24 | int *a1 = test(); 25 | int *b1 = test(); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/dsa/td/recur1.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | int*test1(int *b3) { 9 | return b3+1; 10 | } 11 | 12 | int* test() { 13 | int* a2 = (int*)malloc(sizeof(int)); 14 | *a2 = 10; 15 | 16 | if(*a2 > 5 ) { 17 | return test(); 18 | } 19 | 20 | int *b2 = (int*)malloc(sizeof(int)); 21 | return test1(b2); 22 | 23 | } 24 | 25 | void func() { 26 | 27 | int *a1 = test(); 28 | int *b1 = test(); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /test/dsa/td/recur2.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | int* test1(int*); 8 | 9 | int* test() { 10 | int* a2 = (int*)malloc(sizeof(int)); 11 | *a2 = 10; 12 | 13 | if(*a2 > 5 ) { 14 | return test(); 15 | } 16 | 17 | int *b2 = (int*)malloc(sizeof(int)); 18 | return test1(b2); 19 | 20 | } 21 | 22 | int*test1(int *b3) { 23 | return test()+*b3; 24 | } 25 | 26 | void func() { 27 | 28 | int *a1 = test(); 29 | int *b1 = test(); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /test/dsa/td/recur3.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | int* test1(int*); 8 | 9 | int* test() { 10 | int* a2 = (int*)malloc(sizeof(int)); 11 | *a2 = 10; 12 | 13 | if(*a2 > 5 ) { 14 | return test(); 15 | } 16 | 17 | int *b2 = (int*)malloc(sizeof(int)); 18 | return test1(b2); 19 | 20 | } 21 | 22 | int*test1(int *b3) { 23 | return test()+*b3; 24 | } 25 | 26 | int *test2(int *b4) { 27 | return test() + *b4; 28 | } 29 | void func() { 30 | 31 | int *a1 = test(); 32 | int *b1 = test(); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/dsa/td/scc-flags.ll: -------------------------------------------------------------------------------- 1 | ; This tests some basic TD functionality--but "obscures" it a tad 2 | ; with a callgraph that has DSCallGraph finding SCC's that are 3 | ; not discovered during BU. 4 | ; When this happens, TD misses all kinds of call edges. 5 | ; Same underlying issue as PR12744. 6 | 7 | ; Clearly 'ptr' in main should have the 'stack allocated' flag :) 8 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:ptr+S" 9 | 10 | ; When TD runs, if we're inlining properly, we'll propagate the +S from 11 | ; main down to B. Check this. 12 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "main:ptr+S" 13 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "A:ptr+S" 14 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "B:ptr+S" 15 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 16 | target triple = "x86_64-unknown-linux-gnu" 17 | 18 | define i32 @main() { 19 | %ptr = alloca i32 20 | call void @A(i32* %ptr) 21 | ret i32 0 22 | } 23 | 24 | define internal void @A(i32* %ptr) { 25 | entry: 26 | call void @B(void (void (i32*)*, i32*)* @C, i32* %ptr) 27 | ret void 28 | } 29 | 30 | define internal void @B(void (void (i32*)*, i32*)* %FP, i32* %ptr) { 31 | entry: 32 | call void %FP(void (i32*)* @A, i32* null) 33 | ret void 34 | } 35 | 36 | define internal void @C(void (i32*)* %FP, i32* %ptr) { 37 | call void %FP(i32* %ptr) 38 | ret void 39 | } 40 | -------------------------------------------------------------------------------- /test/dsa/td/scc-global.ll: -------------------------------------------------------------------------------- 1 | ; See scc-flags.ll for the reasoning behind this CFG pattern. 2 | ; This builds on it, but goes a step further to demonstrate: 3 | ; a)we lose track of nodes (Globals, at that!) not just flags 4 | ; b)there's another bug lurking that prevents inlining through 5 | ; the dummy callsites constructed in TD. This is tested 6 | ; by checking that information is indeed propagated from B 7 | ; to C through the callsite within B. 8 | 9 | ; Clearly 'ptr' in main should have the 'stack allocated' flag :) 10 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:ptr+S" 11 | 12 | ; When TD runs, if we're doing things properly, we'll propagate @Global from 13 | ; main down to the load in C. 14 | ; Additionally, at each stage @Global should point to a +S DSNode 15 | ; Check that this is so: 16 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "main:ptr+S" 17 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "A:ptr+G" 18 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "A:ptr:0+S" 19 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "B:ptr+G" 20 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "B:ptr:0+S" 21 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "C:ptr+G" 22 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "C:ptr:0+S" 23 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "C:addr+S" 24 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 25 | target triple = "x86_64-unknown-linux-gnu" 26 | 27 | @Global = internal global i32* null 28 | 29 | define i32 @main() { 30 | %ptr = alloca i32 31 | store i32* %ptr, i32** @Global 32 | call void @A(i32** @Global) 33 | ret i32 0 34 | } 35 | 36 | define internal void @A(i32** %ptr) { 37 | entry: 38 | call void @B(void (void (i32**)*, i32**)* @C, i32** %ptr) 39 | ret void 40 | } 41 | 42 | define internal void @B(void (void (i32**)*, i32**)* %FP, i32** %ptr) { 43 | entry: 44 | call void %FP(void (i32**)* @A, i32** %ptr) 45 | ret void 46 | } 47 | 48 | define internal void @C(void (i32**)* %FP, i32** %ptr) { 49 | %addr = load i32*, i32** %ptr 50 | call void %FP(i32** null) 51 | ret void 52 | } 53 | -------------------------------------------------------------------------------- /test/dsa/td/testcase.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | 8 | 9 | static int* test() { 10 | int* a2 = (int*)malloc(sizeof(int)); 11 | return a2; 12 | 13 | } 14 | 15 | void func() { 16 | 17 | int *a1 = test(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /test/dsa/td/testcase.ll: -------------------------------------------------------------------------------- 1 | ;RUN: dsaopt %s -dsa-local -analyze -verify-flags "func:a1:0+I" 2 | ;RUN: dsaopt %s -dsa-td -analyze -verify-flags "func:a1:0+HM-I" 3 | 4 | ; ModuleID = 'testcase.bc' 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | define internal i32* @test() nounwind { 9 | entry: 10 | %retval = alloca i32* ; [#uses=2] 11 | %0 = alloca i32* ; [#uses=2] 12 | %a2 = alloca i32* ; [#uses=2] 13 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 14 | %1 = call noalias i8* @malloc(i64 4) nounwind ; [#uses=1] 15 | %2 = bitcast i8* %1 to i32* ; [#uses=1] 16 | store i32* %2, i32** %a2, align 8 17 | %3 = load i32*, i32** %a2, align 8 ; [#uses=1] 18 | store i32* %3, i32** %0, align 8 19 | %4 = load i32*, i32** %0, align 8 ; [#uses=1] 20 | store i32* %4, i32** %retval, align 8 21 | br label %return 22 | 23 | return: ; preds = %entry 24 | %retval1 = load i32*, i32** %retval ; [#uses=1] 25 | ret i32* %retval1 26 | } 27 | 28 | declare noalias i8* @malloc(i64) nounwind 29 | 30 | define void @func() nounwind { 31 | entry: 32 | %a1 = alloca i32* ; [#uses=1] 33 | %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] 34 | %0 = call i32* @test() nounwind ; [#uses=1] 35 | store i32* %0, i32** %a1, align 8 36 | br label %return 37 | 38 | return: ; preds = %entry 39 | ret void 40 | } 41 | -------------------------------------------------------------------------------- /test/dsa/types/array2struct.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | ;RUN: dsaopt %s -dsa-local -analyze -check-type=tree,FoldedVOID 5 | ;RUN: dsaopt %s -dsa-local -enable-type-inference-opts -analyze -check-type=tree,12:\[8xi32\]Array 6 | ; LLVM front end converts the type of tree, to a struct type instead of an array of the right type. 7 | ; even though structurally equivalent, DSA cant infer this yet. 8 | 9 | 10 | %0 = type { %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %1, %1, %1, %1, %1, %1, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %struct..0tnode, %1 } 11 | %1 = type { i32, i32, i32, [32 x i8] } 12 | %struct..0tnode = type { i32, i32, i32, [8 x i32] } 13 | 14 | @tree = external global %0, align 32 ; <%0*> [#uses=1] 15 | 16 | define i32 @opening(i32* %i, i32* %j, i32 %type) nounwind { 17 | entry: 18 | br i1 undef, label %bb8, label %bb10 19 | 20 | bb8: ; preds = %entry 21 | br i1 undef, label %bb2.i, label %random_nasko.exit 22 | 23 | bb2.i: ; preds = %bb8 24 | br label %random_nasko.exit 25 | 26 | random_nasko.exit: ; preds = %bb2.i, %bb8 27 | %tmp81moda7 = getelementptr [21 x %struct..0tnode], [21 x %struct..0tnode]* bitcast (%0* @tree to [21 x %struct..0tnode]*), i64 0, i64 undef, i32 3, i64 undef ; [#uses=0] 28 | ret i32 1 29 | 30 | bb10: ; preds = %entry 31 | ret i32 0 32 | } 33 | -------------------------------------------------------------------------------- /test/dsa/types/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/types/union.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | struct StructType { 9 | 10 | float a; 11 | int *b; 12 | }; 13 | union UnionType { 14 | 15 | int a; 16 | int *b; 17 | int c[100]; 18 | struct StructType obj; 19 | 20 | }; 21 | 22 | void func() { 23 | 24 | int *tmp = (int*) malloc(sizeof(int)); 25 | union UnionType s1; 26 | 27 | s1.b = tmp; 28 | 29 | int *c = s1.b; 30 | int d = s1.a; 31 | int arr = s1.c[0]; 32 | struct StructType x = s1.obj; 33 | float y = x.a; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /test/dsa/types/union1.c: -------------------------------------------------------------------------------- 1 | //--Make sure we can run DSA on it! 2 | //RUN: clang %s -c -emit-llvm -o - | \ 3 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 4 | 5 | 6 | #include 7 | struct NestedStructType { 8 | 9 | float a1; 10 | int *b1; 11 | }; 12 | struct StructType { 13 | 14 | float a2; 15 | int *b2; 16 | struct NestedStructType ns2; 17 | }; 18 | union UnionType { 19 | 20 | int a; 21 | int *b; 22 | int c[100]; 23 | struct StructType obj; 24 | 25 | }; 26 | 27 | void func() { 28 | 29 | int *tmp = (int*) malloc(sizeof(int)); 30 | union UnionType s1; 31 | 32 | s1.b = tmp; 33 | 34 | int *c = s1.b; 35 | int d = s1.a; 36 | int arr = s1.c[0]; 37 | struct StructType x = s1.obj; 38 | float y = x.a2; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /test/dsa/types/union2.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | struct StructType1 { 9 | 10 | int a1; 11 | int b1; 12 | int c1; 13 | }; 14 | struct StructType2 { 15 | 16 | int a2; 17 | short b2; 18 | int c2; 19 | }; 20 | 21 | union UnionType { 22 | struct StructType1 s1; 23 | struct StructType2 s2; 24 | }; 25 | 26 | void func() { 27 | 28 | union UnionType obj; 29 | 30 | obj.s1.a1 = 2l; 31 | obj.s1.b1 = 33; 32 | obj.s1.c1 = 22; 33 | 34 | struct StructType2 s = obj.s2; 35 | 36 | int t = obj.s2.c2; 37 | int t1 = obj.s1.c1; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /test/dsa/types/union3.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | struct StructType1 { 9 | 10 | int a1; 11 | int b1; 12 | int c1; 13 | }; 14 | struct StructType2 { 15 | 16 | int a2; 17 | short b2; 18 | short c3; 19 | int c2; 20 | }; 21 | 22 | union UnionType { 23 | struct StructType1 s1; 24 | struct StructType2 s2; 25 | }; 26 | 27 | void func() { 28 | 29 | union UnionType obj; 30 | 31 | obj.s1.a1 = 2l; 32 | obj.s1.b1 = 33; 33 | obj.s1.c1 = 22; 34 | 35 | struct StructType2 s = obj.s2; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /test/dsa/types/union4.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | struct StructType1 { 9 | 10 | int a1; 11 | int b1; 12 | int c1; 13 | }; 14 | struct StructType2 { 15 | 16 | int a2; 17 | short b2; 18 | short c3; 19 | int c2; 20 | }; 21 | 22 | union UnionType { 23 | struct StructType1 s1; 24 | struct StructType2 s2; 25 | }; 26 | 27 | void func() { 28 | 29 | union UnionType obj; 30 | 31 | obj.s1.a1 = 2l; 32 | obj.s1.b1 = 33; 33 | obj.s1.c1 = 22; 34 | 35 | short x = obj.s2.b2; 36 | short y = obj.s2.c3; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /test/dsa/types/union_arrays.c: -------------------------------------------------------------------------------- 1 | 2 | //--Make sure we can run DSA on it! 3 | //RUN: clang %s -c -emit-llvm -o - | \ 4 | //RUN: dsaopt -dsa-bu -dsa-td -disable-output 5 | 6 | 7 | #include 8 | struct StructType1 { 9 | int a1[10]; 10 | short b1[10]; 11 | int c1[10]; 12 | }; 13 | struct StructType2 { 14 | int a2[10]; 15 | int b2[10]; 16 | int c2[10]; 17 | }; 18 | union UnionType { 19 | struct StructType1 s1; 20 | struct StructType2 s2; 21 | }; 22 | 23 | void func() { 24 | 25 | union UnionType obj; 26 | union UnionType obj_copy; 27 | int i; 28 | for(i=0;i<10;i++) { 29 | obj.s1.a1[i] = i + 10; 30 | obj.s1.b1[i] = i + 32; 31 | obj.s1.c1[i] = i + 64; 32 | } 33 | for(i=0;i<10;i++) { 34 | obj_copy.s2.a2[i] = obj.s1.a1[i]; 35 | obj_copy.s2.b2[i] = obj.s1.b1[i]; 36 | obj_copy.s2.c2[i] = obj.s1.c1[i]; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /test/dsa/var_arg/extern.c: -------------------------------------------------------------------------------- 1 | #include 2 | //This tests mod/ref behavior of extern var-arg functions 3 | //We *should* special-case those we know about... 4 | //..but for now we don't: 5 | //XFAIL: * 6 | 7 | //--build the code into a .bc 8 | //RUN: clang -c -O0 %s -S -emit-llvm -o - | llvm-as > %t.bc 9 | //--check if ds-aa breaks, or breaks opts 10 | //RUN: dsaopt %t.bc -ds-aa -O3 -o /dev/null 11 | //--check properties of this particular test 12 | //RUN: dsaopt %t.bc -ds-aa -aa-eval -o /dev/null \ 13 | // RUN: -print-all-alias-modref-info >& %t.aa 14 | 15 | //Unknown external function 16 | //Everything going into this should be assumed to be mod/ref'd 17 | extern void unknown_extern(int, ...); 18 | 19 | int main() 20 | { 21 | int stack_val1 = 5; 22 | int stack_val2 = 10; 23 | int stack_val3 = 15; 24 | int stack_val4 = 20; 25 | int stack_val5 = 25; 26 | int stack_val6 = 30; 27 | 28 | //We should special case this--offhand, modref might be best 29 | //RUN: cat %t.aa | grep {Ptr:.*stack_val1.*scanf} | grep {^\[ \]*ModRef} 30 | //RUN: cat %t.aa | grep {Ptr:.*stack_val2.*scanf} | grep {^\[ \]*ModRef} 31 | scanf("%d, %d\n", &stack_val1, stack_val2); 32 | 33 | //We should special case this--ref's vars, not mod 34 | //RUN: cat %t.aa | grep {Ptr:.*stack_val3.*printf} | grep {^\[ \]*Ref} 35 | //RUN: cat %t.aa | grep {Ptr:.*stack_val4.*printf} | grep {^\[ \]*Ref} 36 | printf("%d, %d\n", &stack_val3, &stack_val4); 37 | 38 | //unknown--this these should be marked modref 39 | //RUN: cat %t.aa | grep {Ptr:.*stack_val5.*unknown_extern} | grep {^\[ \]*ModRef} 40 | //RUN: cat %t.aa | grep {Ptr:.*stack_val6.*unknown_extern} | grep {^\[ \]*ModRef} 41 | unknown_extern( 0, &stack_val5, &stack_val6); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /test/dsa/var_arg/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/dsa/var_arg/multiple_callee.c: -------------------------------------------------------------------------------- 1 | //TODO: Update this to not use ds-aa! 2 | //XFAIL: * 3 | #include 4 | //This tests having multiple parameters 5 | 6 | //What to check: 7 | //'val' should alias stack_val and stack_val2 8 | //'p1' and 'p2' should alias 9 | //'p1' and 'p2' should be modref'd by assign 10 | //(accordingly stack_val/stack_val2 are modref'd) 11 | // 12 | //--build the code into a .bc 13 | //RUN: clang -O0 %s -S -emit-llvm -o - | llvm-as > %t.bc 14 | //--check if ds-aa breaks, breaks opts, or results in miscompiled code 15 | //RUN: lli %t.bc > %t.refout 16 | //RUN: dsaopt %t.bc -ds-aa -gvn -o - | lli > %t.out 17 | //RUN: diff %t.refout %t.out 18 | //--check properties of this particular test 19 | //RUN: dsaopt %t.bc -ds-aa -aa-eval -o /dev/null \ 20 | // RUN: -print-all-alias-modref-info >& %t.aa 21 | //ds-aa should tell us that assign modifies p1 22 | //RUN: cat %t.aa | grep {Ptr:.*p1.*@assign} | grep {^\[ \]*ModRef} 23 | //ds-aa should tell us that assign does something to p2 24 | //RUN: cat %t.aa | grep {Ptr:.*p2.*@assign} | grep -v NoModRef 25 | 26 | 27 | static int assign( int count, ... ) 28 | { 29 | va_list ap; 30 | va_start( ap, count ); 31 | 32 | int sum = 0; 33 | int i = 1; 34 | int ** old = va_arg( ap, int** ); 35 | for ( ; i < count; ++i ) 36 | { 37 | int **val = va_arg( ap, int** ); 38 | *old = *val; 39 | old = val; 40 | } 41 | 42 | va_end( ap ); 43 | 44 | return sum; 45 | } 46 | 47 | int main() 48 | { 49 | int stack_val = 5; 50 | int stack_val2 = 10; 51 | 52 | int * p1 = &stack_val; 53 | int * p2 = &stack_val2; 54 | 55 | //This will change p1 to point to *p2 56 | assign( 2, &p1, &p2 ); 57 | 58 | //This check should succeed, p1 points to stack_val now 59 | if ( p1 != &stack_val ) 60 | { 61 | return 0; 62 | } 63 | return -1; 64 | } 65 | -------------------------------------------------------------------------------- /test/dsa/var_arg/multiple_callee_nomodref.c: -------------------------------------------------------------------------------- 1 | //TODO: Update this to not use ds-aa! 2 | //XFAIL: * 3 | #include 4 | //This tests having multiple parameters 5 | //In particular, this verifies that dsa doesn't unnecessarily 6 | //set the mod/ref flag for functions. 7 | 8 | //What to check: 9 | //'val' should alias stack_val and stack_val2 10 | //'p1' and 'p2' should alias 11 | //'p1' and 'p2' should be modref'd by assign 12 | //(accordingly stack_val/stack_val2 are modref'd) 13 | // 14 | //--build the code into a .bc 15 | //RUN: clang -O0 %s -S -emit-llvm -o - | llvm-as > %t.bc 16 | //--check if ds-aa breaks, breaks opts, or results in miscompiled code 17 | //RUN: lli %t.bc > %t.refout 18 | //RUN: dsaopt %t.bc -ds-aa -gvn -o - | lli > %t.out 19 | //RUN: diff %t.refout %t.out 20 | //--check properties of this particular test 21 | //RUN: dsaopt %t.bc -ds-aa -aa-eval -o /dev/null \ 22 | // RUN: -print-all-alias-modref-info >& %t.aa 23 | //ds-aa should tell us that assign doesn't mod/ref p1 24 | //RUN: cat %t.aa | grep {Ptr:.*p1.*@assign} | grep NoModRef 25 | //ds-aa should tell us that assign doesn't mod/ref p2 26 | //RUN: cat %t.aa | grep {Ptr:.*p2.*@assign} | grep NoModRef 27 | 28 | 29 | static int assign( int count, ... ) 30 | { 31 | va_list ap; 32 | va_start( ap, count ); 33 | 34 | int sum = 0; 35 | int i = 1; 36 | int ** old = va_arg( ap, int** ); 37 | for ( ; i < count; ++i ) 38 | { 39 | int **val = va_arg( ap, int** ); 40 | //Unlike 'multiple_callee.c', don't mod/ref the value 41 | //*old = *val; 42 | old = val; 43 | } 44 | 45 | va_end( ap ); 46 | 47 | return sum; 48 | } 49 | 50 | int main() 51 | { 52 | int stack_val = 5; 53 | int stack_val2 = 10; 54 | 55 | int * p1 = &stack_val; 56 | int * p2 = &stack_val2; 57 | 58 | //Doesn't mod/ref either param 59 | assign( 2, &p1, &p2 ); 60 | 61 | //p1 is still intact, pointing to stack_val 62 | if ( p1 == &stack_val ) 63 | { 64 | return 0; 65 | } 66 | return -1; 67 | } 68 | -------------------------------------------------------------------------------- /test/lit.site.cfg.in: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | ## Autogenerated by LLVM/Clang configuration. 4 | # Do not edit! 5 | config.host_triple = "@LLVM_HOST_TRIPLE@" 6 | config.target_triple = "@TARGET_TRIPLE@" 7 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" 8 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" 9 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" 10 | config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" 11 | config.proj_src_root = "@PROJ_SRC_ROOT@" 12 | config.proj_obj_root = "@PROJ_OBJ_ROOT@" 13 | 14 | config.llvm_shlib_dir = "@SHLIBDIR@" 15 | config.llvm_shlib_ext = "@SHLIBEXT@" 16 | config.llvm_exe_ext = "@EXEEXT@" 17 | config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" 18 | config.python_executable = "@PYTHON_EXECUTABLE@" 19 | config.gold_executable = "@GOLD_EXECUTABLE@" 20 | config.ocamlfind_executable = "@OCAMLFIND@" 21 | config.have_ocamlopt = "@HAVE_OCAMLOPT@" 22 | config.have_ocaml_ounit = "@HAVE_OCAML_OUNIT@" 23 | config.ocaml_flags = "@OCAMLFLAGS@" 24 | config.go_executable = "@GO_EXECUTABLE@" 25 | config.enable_shared = @ENABLE_SHARED@ 26 | config.enable_assertions = @ENABLE_ASSERTIONS@ 27 | config.targets_to_build = "@TARGETS_TO_BUILD@" 28 | config.llvm_bindings = "@LLVM_BINDINGS@".split(' ') 29 | config.host_os = "@HOST_OS@" 30 | config.host_arch = "@HOST_ARCH@" 31 | config.host_cc = "@HOST_CC@" 32 | config.host_cxx = "@HOST_CXX@" 33 | config.host_ldflags = "@HOST_LDFLAGS@" 34 | config.llvm_use_intel_jitevents = "@LLVM_USE_INTEL_JITEVENTS@" 35 | config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" 36 | config.have_zlib = "@HAVE_LIBZ@" 37 | config.have_dia_sdk = @HAVE_DIA_SDK@ 38 | config.enable_ffi = "@LLVM_ENABLE_FFI@" 39 | 40 | # Support substitution of the tools_dir with user parameters. This is 41 | # used when we can't determine the tool dir at configuration time. 42 | try: 43 | config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params 44 | config.llvm_shlib_dir = config.llvm_shlib_dir % lit_config.params 45 | except KeyError: 46 | e = sys.exc_info()[1] 47 | key, = e.args 48 | lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) 49 | 50 | # Let the main config do the real work. 51 | lit_config.load_config(config, "@PROJ_SRC_ROOT@/test/lit.cfg") 52 | -------------------------------------------------------------------------------- /test/pa/clone/AttrTest.ll: -------------------------------------------------------------------------------- 1 | ; This test does some very basic checking on the attribute copying of arguments 2 | ;RUN: paopt %s -paheur-AllButUnreachableFromMemory -poolalloc -o %t.bc |& grep "Pool allocating.*nodes!" 3 | ;|& grep "Pool allocating.*nodes!" 4 | ;RUN: llvm-dis %t.bc -o %t.ll 5 | ; Make sure 'nocapture' attribute isn't copied to new PD argument 6 | ;RUN: cat %t.ll | grep -v ".*@attr_clone(.*nocapture.*,.*,.*)" 7 | ; But ensure the other arguments have their original attributes 8 | ;RUN: cat %t.ll | grep ".*@attr_clone(.*,.*zeroext.*,.*nocapture.*)" 9 | ; Also, ensure sret attributes are dropped from first parameter 10 | ; (verifier also catches this) 11 | ;RUN: cat %t.ll | grep -v ".*@attr2_clone(.*sret.*)" 12 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 13 | target triple = "x86_64-unknown-linux-gnu" 14 | 15 | define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { 16 | entry: 17 | unreachable 18 | } 19 | 20 | define internal void @attr(i16 zeroext %IntParam, i8** nocapture %NeedsPool) { 21 | entry: 22 | unreachable 23 | } 24 | 25 | define internal void @attr2(i8** sret %NeedsPool) { 26 | entry: 27 | unreachable 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/pa/clone/computeNodeMappingFail.ll: -------------------------------------------------------------------------------- 1 | ;This hits an assert in computeNodeMapping, when offset of merging node is greater than 1st node. 2 | ;RUN: paopt %s -paheur-AllButUnreachableFromMemory -poolalloc -o %t.bc |& grep "Pool allocating.*nodes!" 3 | ;RUN: llvm-dis %t.bc -o %t.ll 4 | 5 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 6 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 7 | target triple = "x86_64-unknown-linux-gnu" 8 | 9 | %struct.RefObj = type { i8*, %struct.TypeToken } 10 | %struct.TypeToken = type { i32, i16, i16 } 11 | 12 | define fastcc void @ImageTokenToRef(%struct.TypeToken* %Token, i32 %AttrNum, i32* %Status, i8** nocapture %RefObject) nounwind { 13 | entry: 14 | %RefTkn = alloca %struct.TypeToken, align 8 ; <%struct.TypeToken*> [#uses=1] 15 | br i1 undef, label %bb13, label %bb 16 | 17 | bb: ; preds = %entry 18 | unreachable 19 | 20 | bb13: ; preds = %entry 21 | br i1 undef, label %bb14, label %bb33 22 | 23 | bb14: ; preds = %bb13 24 | br i1 undef, label %bb15, label %bb21 25 | 26 | bb15: ; preds = %bb14 27 | br i1 undef, label %bb17, label %KernelGetAttr.exit 28 | 29 | KernelGetAttr.exit: ; preds = %bb15 30 | unreachable 31 | 32 | bb17: ; preds = %bb15 33 | %tmp62 = call fastcc i32 @ImageGetObject(%struct.TypeToken* %RefTkn, i32* %Status, i8** %RefObject) nounwind ; [#uses=0] 34 | unreachable 35 | 36 | bb21: ; preds = %bb14 37 | br i1 undef, label %bb23, label %KernelGetAttr.exit42 38 | 39 | KernelGetAttr.exit42: ; preds = %bb21 40 | unreachable 41 | 42 | bb23: ; preds = %bb21 43 | %tmp72 = getelementptr inbounds %struct.RefObj, %struct.RefObj* undef, i64 0, i32 1 ; <%struct.TypeToken*> [#uses=1] 44 | %tmp85 = call fastcc i32 @ImageGetObject(%struct.TypeToken* %tmp72, i32* %Status, i8** %RefObject) nounwind ; [#uses=0] 45 | unreachable 46 | 47 | bb33: ; preds = %bb13 48 | ret void 49 | } 50 | 51 | define fastcc i32 @ImageGetObject(%struct.TypeToken* %Token, i32* %Status, i8** nocapture %This) nounwind { 52 | entry: 53 | unreachable 54 | } 55 | -------------------------------------------------------------------------------- /test/pa/clone/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/pa/regression/2010-07-09-ArgAttrMismatch.ll: -------------------------------------------------------------------------------- 1 | ;RUN: paopt %s -paheur-AllButUnreachableFromMemory -poolalloc -disable-output 2>&1 2 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { 6 | entry: 7 | unreachable 8 | } 9 | 10 | define void @attr(i16 zeroext %IntParam, i8* %NeedsPool) { 11 | entry: 12 | unreachable 13 | } 14 | -------------------------------------------------------------------------------- /test/pa/regression/2010-08-17-InvalidIterator.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 2 | ;RUN: paopt %s -paheur-AllButUnreachableFromMemory -poolalloc -disable-output 2>&1 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | %struct.TypHeader = type { i64, %struct.TypHeader**, [3 x i8], i8 } 7 | 8 | define fastcc void @InitEval() nounwind { 9 | bb.nph49: 10 | br label %bb 11 | 12 | bb: ; preds = %bb, %bb.nph49 13 | br i1 undef, label %bb5.preheader, label %bb 14 | 15 | bb4: ; preds = %bb5.preheader, %bb4 16 | br i1 undef, label %bb6, label %bb4 17 | 18 | bb6: ; preds = %bb4 19 | br i1 undef, label %bb11.preheader, label %bb5.preheader 20 | 21 | bb5.preheader: ; preds = %bb6, %bb 22 | br label %bb4 23 | 24 | bb10: ; preds = %bb11.preheader, %bb10 25 | br i1 undef, label %bb14.loopexit, label %bb10 26 | 27 | bb13: ; preds = %bb14.loopexit, %bb13 28 | br i1 undef, label %bb15, label %bb13 29 | 30 | bb14.loopexit: ; preds = %bb10 31 | br i1 undef, label %bb13, label %bb15 32 | 33 | bb15: ; preds = %bb14.loopexit, %bb13 34 | br i1 undef, label %bb17, label %bb11.preheader 35 | 36 | bb11.preheader: ; preds = %bb15, %bb6 37 | br label %bb10 38 | 39 | bb17: ; preds = %bb15 40 | store %struct.TypHeader* bitcast (%struct.TypHeader* (%struct.TypHeader*)* @IntComm to %struct.TypHeader*), %struct.TypHeader** undef 41 | unreachable 42 | } 43 | 44 | define %struct.TypHeader* @IntComm(%struct.TypHeader* nocapture %hdCall) nounwind { 45 | entry: 46 | unreachable 47 | } 48 | 49 | define i32 @main(i32 %argc, i8** nocapture %argv) noreturn nounwind { 50 | entry: 51 | unreachable 52 | } 53 | -------------------------------------------------------------------------------- /test/pa/regression/2010-09-14-Fptr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build this file into bitcode and run poolalloc on it 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: paopt %t.bc -paheur-AllButUnreachableFromMemory -poolalloc -o %t.pa.bc 2>&1 5 | * RUN: clang %t.pa.bc -o %t.pa -L%llvmshlibdir -lpoolalloc_rt -Wl,-rpath %llvmshlibdir 6 | * 7 | * Build the program without poolalloc: 8 | * RUN: clang -o %t.native %s 9 | * 10 | * Execute the program to verify it's correct: 11 | * RUN: %t.pa >& %t.pa.out 12 | * RUN: %t.native >& %t.native.out 13 | * 14 | * Diff the two executions 15 | * RUN: diff %t.pa.out %t.native.out 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define MAGIC 0xBEEF 23 | 24 | typedef void (*FP)(int *); 25 | 26 | void callee(int * v) 27 | { 28 | printf("*v: %d\n", *v); 29 | assert(*v == MAGIC); 30 | } 31 | 32 | FP getFP() 33 | { 34 | return callee; 35 | } 36 | 37 | int main(int argc, char ** argv) 38 | { 39 | int val = MAGIC; 40 | getFP()(&val); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /test/pa/regression/2010-09-14-Fptr_helper.c: -------------------------------------------------------------------------------- 1 | // This is the same as 2010-09-Fptr.c, but does it with a helper 2 | // to verify/illustrate that the issue is /not/ "main"-specific. 3 | // (and to catch fixes that attempt to fix it as such) 4 | /* 5 | * Build this file into bitcode and run poolalloc on it 6 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 7 | * RUN: paopt %t.bc -paheur-AllButUnreachableFromMemory -poolalloc -o %t.pa.bc 2>&1 8 | * RUN: clang %t.pa.bc -o %t.pa -L%llvmshlibdir -lpoolalloc_rt -Wl,-rpath %llvmshlibdir 9 | * 10 | * Build the program without poolalloc: 11 | * RUN: clang -o %t.native %s 12 | * 13 | * Execute the program to verify it's correct: 14 | * RUN: %t.pa >& %t.pa.out 15 | * RUN: %t.native >& %t.native.out 16 | * 17 | * Diff the two executions 18 | * RUN: diff %t.pa.out %t.native.out 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #define MAGIC 0xBEEF 26 | 27 | typedef void (*FP)(int *); 28 | 29 | void callee(int * v) 30 | { 31 | printf("*v: %d\n", *v); 32 | assert(*v == MAGIC); 33 | } 34 | 35 | FP getFP() 36 | { 37 | return callee; 38 | } 39 | 40 | void helper(int *v) 41 | { 42 | getFP()(v); 43 | } 44 | 45 | int main(int argc, char ** argv) 46 | { 47 | int val = MAGIC; 48 | helper(&val); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /test/pa/regression/lit.local.cfg: -------------------------------------------------------------------------------- 1 | config.suffixes = ['.ll', '.c', '.cpp'] 2 | -------------------------------------------------------------------------------- /test/type_checks/correct/basic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: not grep "Type.*mismatch" %t.tc.out 11 | */ 12 | #include 13 | #include 14 | //This is a basic use of vararg pointer use 15 | 16 | static int get( int unused, ... ) 17 | { 18 | va_list ap; 19 | va_start( ap, unused ); 20 | int *val = va_arg( ap, int* ); 21 | va_end( ap ); 22 | 23 | return *val; 24 | } 25 | 26 | int main() 27 | { 28 | int stack_val = 5; 29 | 30 | int ret = get( 0, &stack_val ); 31 | 32 | return ret - 5; 33 | } 34 | -------------------------------------------------------------------------------- /test/type_checks/correct/basic_repeat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: not grep "Type.*mismatch" %t.tc.out 11 | */ 12 | #include 13 | #include 14 | //This is a basic use of vararg pointer use 15 | 16 | static int get( int unused, ... ) 17 | { 18 | va_list ap; 19 | va_start( ap, unused ); 20 | int *val = va_arg( ap, int* ); 21 | va_end( ap ); 22 | va_start( ap, unused ); 23 | int *val1 = va_arg( ap, int* ); 24 | va_end( ap ); 25 | 26 | return *val; 27 | } 28 | 29 | int main() 30 | { 31 | int stack_val = 5; 32 | 33 | int ret = get( 0, &stack_val ); 34 | 35 | return ret - 5; 36 | } 37 | -------------------------------------------------------------------------------- /test/type_checks/correct/vprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: not grep "Type.*mismatch" %t.tc.out 11 | */ 12 | /* vprintf example */ 13 | #include 14 | #include 15 | 16 | void WriteFormatted (char * format, ...) 17 | { 18 | va_list args; 19 | va_start (args, format); 20 | int a = va_arg(args, int); 21 | printf("%d\n", a); 22 | vprintf (format, args); 23 | va_end (args); 24 | } 25 | 26 | int main () 27 | { 28 | WriteFormatted ("Call with %d variable argument.\n",55, 1); 29 | WriteFormatted ("Call with %d variable %s.\n",55, 2,"arguments"); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test/type_checks/correct/vprintf1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: not grep "Type.*mismatch" %t.tc.out 11 | */ 12 | /* vprintf example */ 13 | #include 14 | #include 15 | 16 | void WriteFormatted (char * format, ...) 17 | { 18 | va_list args; 19 | va_start (args, format); 20 | vprintf (format, args); 21 | va_end (args); 22 | } 23 | 24 | int main () 25 | { 26 | WriteFormatted ("Call with %d variable argument.\n",1); 27 | WriteFormatted ("Call with %d variable %s.\n",2,"arguments"); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /test/type_checks/error/IntUnion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: grep "Type.*mismatch" %t.tc.out 11 | */ 12 | 13 | int first_ones[65536]; 14 | 15 | int FirstOne(unsigned long arg1) 16 | { 17 | union doub { 18 | unsigned short i[4]; 19 | unsigned long d; 20 | }; 21 | union doub x; 22 | x.d=arg1; 23 | if (x.i[3]) 24 | return (first_ones[x.i[3]]); 25 | if (x.i[2]) 26 | return (first_ones[x.i[2]]+16); 27 | if (x.i[1]) 28 | return (first_ones[x.i[1]]+32); 29 | if (x.i[0]) 30 | return (first_ones[x.i[0]]+48); 31 | return(64); 32 | } 33 | 34 | int main() { 35 | int a = FirstOne(12345678); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /test/type_checks/error/alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: grep "Type.*mismatch" %t.tc.out 11 | */ 12 | #include 13 | 14 | void **alloc_matrix (int nrmin, int nrmax, int ncmin, int ncmax, 15 | size_t elsize) { 16 | 17 | 18 | int i; 19 | char **cptr; 20 | 21 | cptr = (char **) malloc ((nrmax - nrmin + 1) * sizeof (char *)); 22 | cptr -= nrmin; 23 | for (i=nrmin;i<=nrmax;i++) { 24 | cptr[i] = (char *) malloc ((ncmax - ncmin + 1) * elsize); 25 | cptr[i] -= ncmin * elsize / sizeof(char); /* sizeof(char) = 1 */ 26 | } 27 | return ((void **) cptr); 28 | } 29 | 30 | int main() { 31 | int i; 32 | int j; 33 | int pins_per_clb = 5; 34 | int ** pinloc = (int **) alloc_matrix (0, 3, 0, pins_per_clb-1, sizeof (int)); 35 | 36 | for (i=0;i<=3;i++) 37 | for (j=0;j& %t.tc.out 10 | * RUN: grep "Type.*mismatch" %t.tc.out 11 | */ 12 | #include 13 | 14 | typedef int* (*funcptr)(double *); 15 | 16 | static int *foo(double *d) { 17 | return (int*)d; 18 | } 19 | static int *bar(double *d) { 20 | return (int*)(d+1); 21 | } 22 | int main(int argc, char **argv) 23 | { 24 | 25 | funcptr FP; 26 | FP = &foo; 27 | if(argc > 5) 28 | FP = &bar; 29 | double d = 5.0; 30 | int *t = (*FP)(&d); 31 | int v = *t; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test/type_checks/error/misalign.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: grep "Type.*mismatch" %t.tc.out 11 | */ 12 | 13 | #include 14 | 15 | 16 | typedef unsigned char byte; //!< byte type definition 17 | 18 | int testEndian() 19 | { 20 | short s; 21 | byte *p; 22 | 23 | p=(byte*)&s; 24 | 25 | s=1; 26 | 27 | return (*(p+1)==0); 28 | } 29 | 30 | int main() { 31 | testEndian(); 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/type_checks/error/misalign1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: grep "Type.*mismatch" %t.tc.out 11 | */ 12 | 13 | #include 14 | 15 | 16 | typedef unsigned char byte; //!< byte type definition 17 | 18 | int testEndian() 19 | { 20 | short s; 21 | byte *p; 22 | 23 | p=(byte*)&s; 24 | 25 | *(p+1)=1; 26 | 27 | return (s==0); 28 | } 29 | 30 | int main() { 31 | testEndian(); 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/type_checks/error/testEndian.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Build into bitcode 3 | * RUN: clang -O0 %s -emit-llvm -c -o %t.bc 4 | * RUN: adsaopt -internalize -mem2reg -typechecks %t.bc -o %t.tc.bc 5 | * RUN: tc-link %t.tc.bc -o %t.tc1.bc 6 | * RUN: llc %t.tc1.bc -o %t.tc1.s 7 | * RUN: clang++ %t.tc1.s -o %t.tc2 8 | * Execute 9 | * RUN: %t.tc2 >& %t.tc.out 10 | * RUN: grep "Type.*mismatch" %t.tc.out 11 | */ 12 | 13 | #include 14 | 15 | 16 | typedef unsigned char byte; //!< byte type definition 17 | 18 | int testEndian() 19 | { 20 | short s; 21 | byte *p; 22 | 23 | p=(byte*)&s; 24 | 25 | s=1; 26 | 27 | return (*p==0); 28 | } 29 | 30 | int main() { 31 | testEndian(); 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/type_checks/regression/nomain.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 2 | ; Typechecks should fail, since we don't have a main. 3 | ; RUN: not adsaopt -internalize -mem2reg -typechecks %s 2> %t.err >/dev/null 4 | ; RUN: grep "Assertion.*No main function found" %t.err 5 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6 | target triple = "x86_64-unknown-linux-gnu" 7 | 8 | define void @fmtfp() nounwind uwtable { 9 | entry: 10 | unreachable 11 | } 12 | -------------------------------------------------------------------------------- /test/type_checks/regression/simple_varargs.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'bugpoint-reduced-simplified.bc' 2 | ; RUN: adsaopt -typechecks %s 3 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | define void @mdprintf(...) nounwind uwtable { 7 | entry: 8 | ret void 9 | } 10 | 11 | define void @main() nounwind uwtable { 12 | entry: 13 | ret void 14 | } 15 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Discover the projects that use CMake in the subdirectories. 2 | # Note that explicit cmake invocation is required every time a new project is 3 | # added or removed. 4 | file(GLOB entries *) 5 | add_subdirectory("WatchDog") 6 | #foreach(entry ${entries}) 7 | # if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt) 8 | # add_subdirectory(${entry}) 9 | # endif() 10 | #endforeach(entry) 11 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Relative path to the top of the source tree. 3 | # 4 | LEVEL=.. 5 | 6 | # 7 | # List all of the subdirectories that we will compile. 8 | # 9 | PARALLEL_DIRS=WatchDog 10 | 11 | include $(LEVEL)/Makefile.common 12 | -------------------------------------------------------------------------------- /tools/Pa/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS bitreader bitwriter instrumentation scalaropts ipo nativecodegen) 2 | add_definitions(-fno-exceptions) 3 | add_llvm_tool( pa pa.cpp ) 4 | target_link_libraries(pa LLVMDataStructure poolalloc) 5 | -------------------------------------------------------------------------------- /tools/Pa/Makefile: -------------------------------------------------------------------------------- 1 | #===- tools/pa/Makefile ------------------------------------*- Makefile -*-===## 2 | # 3 | # Automatic Pool Allocation Project 4 | # 5 | # This file was developed by the LLVM research group and is distributed under 6 | # the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | # 8 | ##===----------------------------------------------------------------------===## 9 | 10 | LEVEL = ../.. 11 | TOOLNAME=pa 12 | 13 | # Initialize the USEDLIBS so we can add to it 14 | 15 | LINK_COMPONENTS := bitreader bitwriter instrumentation scalaropts ipo \ 16 | nativecodegen 17 | USEDLIBS := poolalloc.a LLVMDataStructure.a 18 | 19 | # Include this here so we can get the configuration of the targets 20 | # that have been configured for construction. We have to do this 21 | # early so we can set up USEDLIBS properly before includeing Makefile.rules 22 | include $(LEVEL)/Makefile.common 23 | 24 | 25 | -------------------------------------------------------------------------------- /tools/TypeChecker/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS bitreader bitwriter instrumentation scalaropts ipo nativecodegen) 2 | add_definitions(-fno-exceptions) 3 | add_llvm_tool( tc tc.cpp ) 4 | target_link_libraries(tc LLVMDataStructure AssistDS ) 5 | -------------------------------------------------------------------------------- /tools/TypeChecker/Makefile: -------------------------------------------------------------------------------- 1 | #===- tools/pa/Makefile ------------------------------------*- Makefile -*-===## 2 | # 3 | # Automatic Pool Allocation Project 4 | # 5 | # This file was developed by the LLVM research group and is distributed under 6 | # the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | # 8 | ##===----------------------------------------------------------------------===## 9 | 10 | LEVEL = ../.. 11 | TOOLNAME=tc 12 | 13 | # Initialize the USEDLIBS so we can add to it 14 | 15 | LINK_COMPONENTS := bitreader bitwriter instrumentation scalaropts ipo \ 16 | nativecodegen 17 | USEDLIBS := poolalloc.a LLVMDataStructure.a AssistDS.a 18 | 19 | # Include this here so we can get the configuration of the targets 20 | # that have been configured for construction. We have to do this 21 | # early so we can set up USEDLIBS properly before includeing Makefile.rules 22 | include $(LEVEL)/Makefile.common 23 | 24 | 25 | -------------------------------------------------------------------------------- /tools/WatchDog/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS bitreader bitwriter instrumentation scalaropts ipo nativecodegen) 2 | add_definitions(-fno-exceptions) 3 | add_llvm_tool( watchdog WatchDog.cpp ) 4 | -------------------------------------------------------------------------------- /tools/WatchDog/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | The WatchDog program is covered under the University of Illinois Open Source 2 | License (located in the top-level source directory). The source code also 3 | contains code posted by Terry Lambert to Apple Computer's unix-porting mailing 4 | list. 5 | -------------------------------------------------------------------------------- /tools/WatchDog/Makefile: -------------------------------------------------------------------------------- 1 | #===- tools/sc/Makefile ------------------------------------*- Makefile -*-===## 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file was developed by the LLVM research group and is distributed under 6 | # the University of Illinois Open Source License. See LICENSE.TXT for details. 7 | # 8 | ##===----------------------------------------------------------------------===## 9 | 10 | LEVEL = ../.. 11 | TOOLNAME=watchdog 12 | 13 | include $(LEVEL)/Makefile.common 14 | 15 | -------------------------------------------------------------------------------- /utils/NightlyCronTab: -------------------------------------------------------------------------------- 1 | # 2 | # Send mail to no one 3 | # 4 | MAILTO="" 5 | 6 | # 7 | # Taken from the Linux man page and modified. 8 | # 9 | 0 3 * * * $HOME/cronjobs/llvm27/projects/poolalloc/utils/NightlyTest.sh 10 | 11 | -------------------------------------------------------------------------------- /utils/NightlyTest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Location of the LLVM source and object trees 4 | LLVMDIR=$HOME/cronjobs/llvm27 5 | 6 | # Location of test suite object tree 7 | TESTSUITE=$LLVMDIR/projects/test-suite 8 | 9 | # Location of file containing log of the test build and run 10 | LOGFILE=$LLVMDIR/projects/poolalloc/test/results 11 | 12 | # List of directories to clean before test 13 | TESTDIRS="MultiSource/Benchmarks/Olden External/SPEC/CINT2000" 14 | 15 | # 16 | # Switch to the LLVM source tree. 17 | # 18 | cd $LLVMDIR 19 | 20 | # 21 | # Make sure LLVM is up-to-date. 22 | # 23 | echo "Updating LLVM" 24 | svn up 25 | echo "Building LLVM" 26 | make -s -j3 tools-only 27 | 28 | # 29 | # Update and build Automatic Pool Allocation 30 | # 31 | cd $LLVMDIR/projects/poolalloc 32 | echo "Updating Poolalloc" 33 | svn up 34 | echo "Building Poolalloc" 35 | make -s -j3 36 | 37 | # 38 | # Clean out the old test files. 39 | # 40 | echo "Cleaning out old test files..." 41 | for dir in $TESTDIRS 42 | do 43 | cd $TESTSUITE/$dir 44 | make clean 45 | done 46 | 47 | # 48 | # Run the automatic pool allocation tests. 49 | # 50 | echo "Testing Poolalloc..." 51 | cd $LLVMDIR/projects/poolalloc/test 52 | mv $LOGFILE $LOGFILE.old 53 | make NO_STABLE_NUMBERS=1 -j3 progtest 2>&1 > $LOGFILE 54 | 55 | # 56 | # Print out the results. 57 | # 58 | for dir in $TESTDIRS 59 | do 60 | cat $TESTSUITE/$dir/report.poolalloc.txt 61 | done 62 | 63 | --------------------------------------------------------------------------------